Compare commits
54 Commits
build3
...
build2016.
Author | SHA1 | Date | |
---|---|---|---|
740ae124f9 | |||
17977d2a88 | |||
ed29923d2e | |||
6228e7229b | |||
677f92af68 | |||
ce43d8b30e | |||
09470e85ce | |||
bab896aba1 | |||
519381684d | |||
a66b35190f | |||
5b655d7889 | |||
e22839168d | |||
7036f5c5ca | |||
a943da1812 | |||
2426ed782e | |||
8caf879b5c | |||
972702a1c6 | |||
438e2fb494 | |||
d66db99241 | |||
a8bebc2808 | |||
23ecd43fc0 | |||
fe7a085c39 | |||
194b4f9bdc | |||
5099ac9621 | |||
70a3f2fff3 | |||
ed49bcca00 | |||
4918c74d49 | |||
e528aa1eec | |||
f5608576c9 | |||
d00e8cf64f | |||
42c8d9bbb7 | |||
dc88d68a6c | |||
b278c8cde9 | |||
47bab9d2c4 | |||
6ef97389a0 | |||
7bac05e63b | |||
e8e8dd91bc | |||
ba31b40d9b | |||
8d9082235b | |||
2b9aa467bd | |||
4df4e620c1 | |||
d269888edc | |||
f46033cac5 | |||
b9af6ced83 | |||
f30a099bf4 | |||
24140f9e42 | |||
68e659d751 | |||
2cf9ee3c46 | |||
06c3fb58a7 | |||
5ac17087f4 | |||
8e8922b78e | |||
1981093293 | |||
6634ed8e4c | |||
336a331c52 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,3 +7,4 @@ src/bootstrap.exe
|
||||
src/Microsoft.VC90.CRT
|
||||
src/Microsoft.VC90.MFC
|
||||
src/documentation/
|
||||
src/com_cache/
|
67
README.md
67
README.md
@@ -8,8 +8,8 @@ Socializer's functionality is far to be perfect, in fact there are lots of metho
|
||||
|
||||
Before downloading, take in to account the following: This source code is completely experimental. The current functionality in this application is not very useful. If you decide to use nightly build versions, take into account that this doesn't work as an application for everyday use yet.
|
||||
|
||||
Version: 2016.05.25
|
||||
Build date: May 25 2016
|
||||
Version: 2016.07.9
|
||||
Build date: Jul 9 2016
|
||||
[Download socializer weekly build](https://github.com/manuelcortez/socializer/blob/master/nightly/socializer-nightly-build.zip?raw=true)
|
||||
|
||||
I have started this effort as an open source project on Feb 13, 2016. Pull requests and bug reports are welcome. Socializer is not a definitive name for this project, it could be changed in future.
|
||||
@@ -21,74 +21,19 @@ I have started this effort as an open source project on Feb 13, 2016. Pull requ
|
||||
* [Python windows extensions (pywin32)](http://www.sourceforge.net/projects/pywin32/) for python 2.7, build 220
|
||||
* [PyEnchant,](http://pythonhosted.org/pyenchant/) version 1.6.6.
|
||||
* [VK API bindings for Python](https://github.com/dimka665/vk) (already included in the SRC directory)
|
||||
* If you want to build your own versions, [Pandoc](http://pandoc.org/installing.html) make sure you have pandoc.exe in your path variable. If not, edit scripts/build.sh.
|
||||
* pypubsub
|
||||
* configobj
|
||||
* requests-oauthlib
|
||||
* future
|
||||
* arrow==0.6
|
||||
* microsofttranslator
|
||||
* [Pandoc](http://pandoc.org/installing.html) for generating the changelog.
|
||||
|
||||
## Running
|
||||
## Documentation
|
||||
|
||||
Just open the main.py file with the python interpreter. This file is located in the src directory. If you haven't configured your VK account, you will see a dialogue, just press yes and a new dialogue will prompt for an user email or phone number and the password for your account. Take into account that the provided information will be saved in a config file as plain text. This application will need your information for renegotiating the access token when it expires.
|
||||
I am trying to write an updated manual for socializer. It can be found in the documentation folder once the program zip file is uncompressed, or in the manual.md file (in markdown). The idea of this manual is to be updated as socializer receives new features or improvements.
|
||||
|
||||
Note: Every time you grant access to socializer, probably You will receive an email from VK by telling you that someone has accessed to your account. It means that a new token has been negotiated between VK and socializer by using an authomatic process, you should ignore those advices, unless you receive an email when you are not logged in VK with socializer or other application. You can see your authorised applications in the configuration section in the VK website. New tokens are renegotiated every 24 hours.
|
||||
|
||||
## Main interface
|
||||
|
||||
If you have used [TWBlue](https://github.com/manuelcortez/twblue) before, the socializer's interface is quite similar. Once you have authorised your account, you will see a window with the following elements:
|
||||
|
||||
* A tree view at the left of the window, where you will see the list of buffers (at the moment, there are only five of these: news feed, my wall, my audios, populars and recommended). These buffers are divided in two categories, posts and music. You could expand each category for seeing the child buffers. There are some additional buffers, timelines and chats, wich will be filled with timelines for your friends or with chats, when you start or receive a chat session.
|
||||
* A button for making a post to your wall.
|
||||
* In audio buffers, Two buttons: Play and play all.
|
||||
* A list where you will see the posts for the currently selected buffer.
|
||||
* A status bar where the program will put some useful information about what it's doing at the moment.
|
||||
* And a menu bar, which could be used for making a search for audio files in VK, or check for updates.
|
||||
|
||||
When socializer starts, it will try to load your news items, wall and audios. At the moment there are only a few supported actions for these items:
|
||||
|
||||
* Audio files: You can play the currently selected song, view the song's details (including lyrics, if available), add or remove from your library, and download it to a desired place in your hard drive. You can find audio files in your news feed or in your own audios buffers.
|
||||
* News feed's post: In your news feed buffer, you can press return in any post and socializer will open a new dialogue which can be different, depending in the kind of post you are when the return key was pressed.
|
||||
* At the moment you can't open your wall posts.
|
||||
|
||||
### Making a post
|
||||
|
||||
When you press the post button, a new dialogue will show up. This dialogue allows you to post something in your wall. In this dialogue you have to write a message. You can translate your message and fix your spelling mistakes. Also you can post an URL address, socializer will try to add it as an attachment, so you will not have to worry about this. When you're ready, just press the send button and it'll be done.
|
||||
|
||||
### Working with posts in news feed
|
||||
|
||||
You can press the return key in any post in your news feed for opening a new dialogue with some information. The information and dialogue will be different if you are viewing a friendship's notification (when someone has added some friends), an audio file, or a regular post.
|
||||
|
||||
If you open a regular post in your newsfeed, you will be able to see the comments in a list, indicate if you do like or dislike the post, or add a new comment.
|
||||
|
||||
For friend notifications, you can only view the new added friends in a list and there are some kind of posts that aren't handled. It should be improved.
|
||||
|
||||
### Working with songs
|
||||
|
||||
If you want to play or view audio's details, you'll have to navigate to the tree view, and, using the down arrow, look for "my audios", "populars" or "Recommendations". You will see two more buttons, play and play all. The play button will play the currently selected audio, and the play all button will play audios in the current buffer, starting with the current selected item. You can go to the song's list, look for a desired song and press the play button, or Ctrl+return, which is a keyboard shorcut. Take in to account that there are some keyboard shorcuts that only work in the list of items.
|
||||
|
||||
You can play audio from any buffer, just press ctrl+return for making the audio playback possible.
|
||||
|
||||
If someone has added multiple audios at once to his library, you will see something like this in your newsfeed: "(friend) has added 4 audios: audio 1, audio2, audio3 and audio4". You can press return in the post for opening the audio's details dialogue, where you will be able to see a list with these audios. By default the first detected song is selected, which means that you could read its details by pressing tab, download or add it to your library. If you change the audio in the list, the information will be updated and you will see details and actions will take effect in the new selected audio.
|
||||
|
||||
When an audio file is playing, you can press f5 and f6 for decreasing and increasing volume, respectively, or control+shift+return for play/pause.
|
||||
|
||||
If you want to see some details for the selected audio file, you can do it by pressing the return key. You will be able to read some useful information (title, artist, duration and the lyric, if available). Also you will be able to download the song to your hard drive, you have to press the download button in the details' dialogue.
|
||||
|
||||
When the download starts, you can close the details dialogue and check the status bar in the main window for seeing the current progress.
|
||||
|
||||
## menu Bar
|
||||
|
||||
You can go to the menu bar by pressing ALT. Right now, there are only two menus, buffer and help:
|
||||
|
||||
### Buffer menu
|
||||
|
||||
* New buffer: This submenu allows you to create a new buffer, at the moment, you can create only a kind of buffer, an audio search. The audio search will be located in the music category and will have the last 299 results of your query. It isn't possible to delete the buffers until you restart the client.
|
||||
* Update current buffer: perform an update operation in the selected buffer, which will retrieve the new items.
|
||||
* Remove buffer: Tries to remove the current buffer. It only works with audio searches, because the default buffers shouldn't be removed.
|
||||
|
||||
The help menu is self explanatory.
|
||||
A copy of the English version of the manual can be read here: [Manual in the socializer's wiki](https://github.com/manuelcortez/socializer/wiki/manual)
|
||||
|
||||
## Contributing
|
||||
|
||||
|
23
changelog.md
23
changelog.md
@@ -1,6 +1,27 @@
|
||||
% Changelog
|
||||
|
||||
## Changes for the current build ()
|
||||
## Changes for the current build (08/07/2016)
|
||||
|
||||
* Removed platform from "last seen" column in the friends list as it could cause some problems and it was being not so exact.
|
||||
* Now deleted audios are not parsed and displayed as "audio removed from library". They are silently ignored.
|
||||
* It's possible to open a friends timeline for others.
|
||||
* Fixed some strange bugs in the built version.
|
||||
* Deactivated accounts will not cause problems in friends lists. They will be displayed as deactivated, wich means that it'll be impossible to interact with those accounts.
|
||||
* When opened, the client will set online for the user account, it'll inform VK that this user is currently online. This parameter will be updated every 15 minutes, as stated in the API documentation.
|
||||
* When opened, socializer will try to create chat buffers for all unread messages.
|
||||
* Update some information on certain posts when an item is selected. For example, update the date of a post.
|
||||
* Read messages will be marked as read in the social network, so it'll cause that your friends could see that you have read the message and socializer will not load chat buffers with read messages at startup.
|
||||
* Included a brief manual in the help menu. Currently available only in English.
|
||||
* Included a context menu in list items. Currently there are functions not available. Menu for chat buffers is not implemented yet.
|
||||
* Implemented audio album load (in the music buffer), creation (in the application menu) and deletion (in the application menu, too).
|
||||
* audios can be moved to albums by pressing the menu key or doing a right click in the item, and selecting "move to album". Audios will be added to the album in the next update (there is a programmed update every 3 minutes), or you can update the buffer manually (from the buffer menu in the menu bar). This option will be available in audio buffers (searches, popular and recommended audio buffers, and audio timelines).
|
||||
* Albums will be empty at startup. In order to get the album's audios, you'll have to navigate to the album and press the button "load". It'll load the needed information for displaying and playing the added songs
|
||||
* If the config is invalid (for example you changed email or phone in the VK site and didn't changed that in Socializer, or just entered invalid credentials), the program will display an error with instructions for fixing the problem.
|
||||
* Now is possible to press enter in the password or email/phone field and it'll do the action of the OK button.
|
||||
* If you have set russian as the main language in the VK site, you'll see names in genitive and instrumental cases in certain phrases.
|
||||
* Updated russian and spanish translations.
|
||||
|
||||
## Changes on build 2016.05.25
|
||||
|
||||
* Added grouped controls in the audio searches dialogue. It will be more accessible so screen readers could detect and read the label for radio buttons.
|
||||
* Added documents to the list of supported attachments in the post viewer. The action for this kind of attachments is to open the default web browser, pointing to the URL address of that file.
|
||||
|
0
doc/__init__.py
Normal file
0
doc/__init__.py
Normal file
12
doc/application.py
Normal file
12
doc/application.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
name = "Socializer"
|
||||
version = "0.13"
|
||||
author = u"Manuel Cortéz"
|
||||
authorEmail = "manuel@manuelcortez.net"
|
||||
copyright = u"Copyright (C) 2016, Manuel cortéz."
|
||||
description = unicode(name+" Is an accessible VK client for Windows.")
|
||||
url = "https://github.com/manuelcortez/socializer"
|
||||
update_url = "https://raw.githubusercontent.com/manuelcortez/socializer/master/update-files/socializer.json"
|
||||
# The short name will be used for detecting translation files. See languageHandler for more details.
|
||||
short_name = "socializer"
|
||||
translators = [u"Valeria K (Russian)", u"Manuel Cortez (Spanish)"]
|
28
doc/documentation_importer.py
Normal file
28
doc/documentation_importer.py
Normal file
@@ -0,0 +1,28 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
""" This script converts the hold documentation (saved in markdown files) in a python file with a list of strings to translate it using gettext."""
|
||||
|
||||
def prepare_documentation_in_file(fileSource, fileDest):
|
||||
""" This takes documentation written in a markdown file and put all the contents in a python file, to create a internationalized documentation.
|
||||
@fileSource str: A markdown(.md) file.
|
||||
@fileDest str: A file where this will put the new strings"""
|
||||
|
||||
f1 = open(fileSource, "r")
|
||||
f2 = open(fileDest, "w")
|
||||
lns = f1.readlines()
|
||||
f2.write("# -*- coding: utf-8 -*-\n")
|
||||
f2.write("documentation = [\n")
|
||||
for i in lns:
|
||||
if "\n" == i:
|
||||
newvar = "\"\","
|
||||
elif "\n" == i[-1]:
|
||||
newvar = "_(u\"\"\"%s\"\"\"),\n" % (i[:-1])
|
||||
else:
|
||||
newvar = "_(u\"\"\"%s\"\"\"),\n" % (i)
|
||||
# print i[-1:]
|
||||
f2.write(newvar)
|
||||
f1.close()
|
||||
f2.write("]")
|
||||
f2.close()
|
||||
|
||||
|
||||
prepare_documentation_in_file("manual.md", "strings.py")
|
42
doc/generator.py
Normal file
42
doc/generator.py
Normal file
@@ -0,0 +1,42 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import markdown
|
||||
import os
|
||||
from codecs import open as _open
|
||||
import languageHandler
|
||||
languageHandler.setLanguage("en")
|
||||
import documentation_importer
|
||||
|
||||
# the list of supported language codes of TW Blue
|
||||
languages = ["en", "es"]
|
||||
|
||||
def generate_document(language):
|
||||
import strings
|
||||
reload(languageHandler)
|
||||
languageHandler.setLanguage(language)
|
||||
reload(strings)
|
||||
markdown_file = markdown.markdown("\n".join(strings.documentation[1:]), extensions=["markdown.extensions.toc"])
|
||||
first_html_block = """<!doctype html>
|
||||
<html lang="%s">
|
||||
<head>
|
||||
<title>%s</title>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<header><h1>%s</h1></header>
|
||||
""" % (language, strings.documentation[0], strings.documentation[0])
|
||||
first_html_block = first_html_block+ markdown_file
|
||||
first_html_block = first_html_block + "\n</body>\n</html>"
|
||||
if not os.path.exists(language):
|
||||
os.mkdir(language)
|
||||
mdfile = _open("%s/manual.html" % language, "w", encoding="utf-8")
|
||||
mdfile.write(first_html_block)
|
||||
mdfile.close()
|
||||
|
||||
def create_documentation():
|
||||
print("Creating documentation in the supported languages...\n")
|
||||
for i in languages:
|
||||
print("Creating documentation for: %s" % (i,))
|
||||
generate_document(i)
|
||||
print("Done")
|
||||
|
||||
create_documentation()
|
176
doc/languageHandler.py
Normal file
176
doc/languageHandler.py
Normal file
@@ -0,0 +1,176 @@
|
||||
import __builtin__
|
||||
import os
|
||||
import sys
|
||||
import ctypes
|
||||
import locale
|
||||
import gettext
|
||||
#import paths
|
||||
import platform
|
||||
|
||||
# A fix for the mac locales
|
||||
if platform.system() != 'Windows':
|
||||
if locale.getlocale()[0] is None:
|
||||
locale.setlocale(locale.LC_ALL, 'en_US')
|
||||
|
||||
#a few Windows locale constants
|
||||
LOCALE_SLANGUAGE=0x2
|
||||
LOCALE_SLANGDISPLAYNAME=0x6f
|
||||
|
||||
curLang="en"
|
||||
|
||||
def localeNameToWindowsLCID(localeName):
|
||||
"""Retreave the Windows locale identifier (LCID) for the given locale name
|
||||
@param localeName: a string of 2letterLanguage_2letterCountry or or just 2letterLanguage
|
||||
@type localeName: string
|
||||
@returns: a Windows LCID
|
||||
@rtype: integer
|
||||
"""
|
||||
#Windows Vista is able to convert locale names to LCIDs
|
||||
func_LocaleNameToLCID=getattr(ctypes.windll.kernel32,'LocaleNameToLCID',None)
|
||||
if func_LocaleNameToLCID is not None:
|
||||
localeName=localeName.replace('_','-')
|
||||
LCID=func_LocaleNameToLCID(unicode(localeName),0)
|
||||
else: #Windows doesn't have this functionality, manually search Python's windows_locale dictionary for the LCID
|
||||
localeName=locale.normalize(localeName)
|
||||
if '.' in localeName:
|
||||
localeName=localeName.split('.')[0]
|
||||
LCList=[x[0] for x in locale.windows_locale.iteritems() if x[1]==localeName]
|
||||
if len(LCList)>0:
|
||||
LCID=LCList[0]
|
||||
else:
|
||||
LCID=0
|
||||
return LCID
|
||||
|
||||
def getLanguageDescription(language):
|
||||
"""Finds out the description (localized full name) of a given local name"""
|
||||
desc=None
|
||||
if platform.system() == "Windows":
|
||||
LCID=localeNameToWindowsLCID(language)
|
||||
if LCID!=0:
|
||||
buf=ctypes.create_unicode_buffer(1024)
|
||||
if '_' not in language:
|
||||
res=ctypes.windll.kernel32.GetLocaleInfoW(LCID,LOCALE_SLANGDISPLAYNAME,buf,1024)
|
||||
else:
|
||||
res=0
|
||||
if res==0:
|
||||
res=ctypes.windll.kernel32.GetLocaleInfoW(LCID,LOCALE_SLANGUAGE,buf,1024)
|
||||
desc=buf.value
|
||||
elif platform.system() == "Linux" or not desc:
|
||||
desc={
|
||||
"am":pgettext("languageName","Amharic"),
|
||||
"an":pgettext("languageName","Aragonese"),
|
||||
"es":pgettext("languageName","Spanish"),
|
||||
"pt":pgettext("languageName","Portuguese"),
|
||||
"ru":pgettext("languageName","Russian"),
|
||||
"it":pgettext("languageName","italian"),
|
||||
"tr":pgettext("languageName","Turkey"),
|
||||
"gl":pgettext("languageName","Galician"),
|
||||
"ca":pgettext("languageName","Catala"),
|
||||
"eu":pgettext("languageName","Vasque"),
|
||||
"pl":pgettext("languageName","polish"),
|
||||
"ar":pgettext("languageName","Arabic"),
|
||||
"ne":pgettext("languageName","Nepali"),
|
||||
"sr":pgettext("languageName","Serbian (Latin)"),
|
||||
}.get(language,None)
|
||||
return desc
|
||||
|
||||
def getAvailableLanguages():
|
||||
"""generates a list of locale names, plus their full localized language and country names.
|
||||
@rtype: list of tuples
|
||||
"""
|
||||
#Make a list of all the locales found in NVDA's locale dir
|
||||
l=[x for x in os.listdir("locales") if not x.startswith('.')]
|
||||
l=[x for x in l if os.path.isfile('locales/%s/LC_MESSAGES/socializer-doc.mo' % x)]
|
||||
#Make sure that en (english) is in the list as it may not have any locale files, but is default
|
||||
if 'en' not in l:
|
||||
l.append('en')
|
||||
l.sort()
|
||||
#For each locale, ask Windows for its human readable display name
|
||||
d=[]
|
||||
for i in l:
|
||||
desc=getLanguageDescription(i)
|
||||
label="%s, %s"%(desc,i) if desc else i
|
||||
d.append(label)
|
||||
#include a 'user default, windows' language, which just represents the default language for this user account
|
||||
l.append("system")
|
||||
# Translators: the label for the Windows default NVDA interface language.
|
||||
d.append(_("User default"))
|
||||
#return a zipped up version of both the lists (a list with tuples of locale,label)
|
||||
return zip(l,d)
|
||||
|
||||
def makePgettext(translations):
|
||||
"""Obtaina pgettext function for use with a gettext translations instance.
|
||||
pgettext is used to support message contexts,
|
||||
but Python 2.7's gettext module doesn't support this,
|
||||
so NVDA must provide its own implementation.
|
||||
"""
|
||||
if isinstance(translations, gettext.GNUTranslations):
|
||||
def pgettext(context, message):
|
||||
message = unicode(message)
|
||||
try:
|
||||
# Look up the message with its context.
|
||||
return translations._catalog[u"%s\x04%s" % (context, message)]
|
||||
except KeyError:
|
||||
return message
|
||||
else:
|
||||
def pgettext(context, message):
|
||||
return unicode(message)
|
||||
return pgettext
|
||||
|
||||
def setLanguage(lang):
|
||||
system = platform.system()
|
||||
global curLang
|
||||
try:
|
||||
if lang=="system":
|
||||
if system == "Windows":
|
||||
windowsLCID=ctypes.windll.kernel32.GetUserDefaultUILanguage()
|
||||
localeName=locale.windows_locale[windowsLCID]
|
||||
else:
|
||||
localeName=locale.getlocale()[0]
|
||||
trans=gettext.translation('socializer-doc', localedir="locales", languages=[localeName])
|
||||
curLang=localeName
|
||||
else:
|
||||
trans=gettext.translation("socializer-doc", localedir="locales", languages=[lang])
|
||||
curLang=lang
|
||||
localeChanged=False
|
||||
#Try setting Python's locale to lang
|
||||
try:
|
||||
locale.setlocale(locale.LC_ALL, lang)
|
||||
localeChanged=True
|
||||
except:
|
||||
pass
|
||||
if not localeChanged and '_' in lang:
|
||||
#Python couldn'tsupport the language_country locale, just try language.
|
||||
try:
|
||||
locale.setlocale(locale.LC_ALL, lang.split('_')[0])
|
||||
except:
|
||||
pass
|
||||
#Set the windows locale for this thread (NVDA core) to this locale.
|
||||
if system == "Windows":
|
||||
LCID=localeNameToWindowsLCID(lang)
|
||||
ctypes.windll.kernel32.SetThreadLocale(LCID)
|
||||
except IOError:
|
||||
trans=gettext.translation("socializer-doc",fallback=True)
|
||||
curLang="en"
|
||||
trans.install(unicode=True)
|
||||
# Install our pgettext function.
|
||||
__builtin__.__dict__["pgettext"] = makePgettext(trans)
|
||||
|
||||
def getLanguage():
|
||||
return curLang
|
||||
|
||||
def normalizeLanguage(lang):
|
||||
"""
|
||||
Normalizes a language-dialect string in to a standard form we can deal with.
|
||||
Converts any dash to underline, and makes sure that language is lowercase and dialect is upercase.
|
||||
"""
|
||||
lang=lang.replace('-','_')
|
||||
ld=lang.split('_')
|
||||
ld[0]=ld[0].lower()
|
||||
#Filter out meta languages such as x-western
|
||||
if ld[0]=='x':
|
||||
return None
|
||||
if len(ld)>=2:
|
||||
ld[1]=ld[1].upper()
|
||||
return "_".join(ld)
|
||||
|
BIN
doc/locales/es/LC_MESSAGES/socializer-doc.mo
Normal file
BIN
doc/locales/es/LC_MESSAGES/socializer-doc.mo
Normal file
Binary file not shown.
535
doc/locales/es/LC_MESSAGES/socializer-doc.po
Normal file
535
doc/locales/es/LC_MESSAGES/socializer-doc.po
Normal file
@@ -0,0 +1,535 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Socializer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-06-29 13:33-0500\n"
|
||||
"PO-Revision-Date: 2016-06-29 16:25-0600\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Manuel Cortez <manuel@manuelcortez.net>\n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.6.11\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. Translators: the label for the Windows default NVDA interface language.
|
||||
msgid "User default"
|
||||
msgstr ""
|
||||
|
||||
msgid "socializer's manual "
|
||||
msgstr "Manual de Socializer"
|
||||
|
||||
msgid "## Introduction"
|
||||
msgstr "## Introducción"
|
||||
|
||||
msgid ""
|
||||
"Socializer is an application to use [VK.com](https://vk.com) in an easy and "
|
||||
"accessible way with minimal CPU resource usage. Socializer will allow you to "
|
||||
"interact with the VK social network by giving you access to the most "
|
||||
"relevant features such as:"
|
||||
msgstr ""
|
||||
"Socializer es una aplicación para usar [vk.com](http://vk.com) de forma "
|
||||
"fácil y accesible, con un consumo de CPU mínimo. Socializer te permitirá "
|
||||
"interactuar con la red social VK, brindándote acceso a las características "
|
||||
"más relevantes, tales como:"
|
||||
|
||||
msgid "* Basic post creation in your wall (including photos)."
|
||||
msgstr ""
|
||||
"* Creación básica de publicaciones en tu muro (incluyendo subida de fotos)"
|
||||
|
||||
msgid "* Audio addition, removal, download and search."
|
||||
msgstr "* Añadir, descargar y buscar archivos de audio."
|
||||
|
||||
msgid "* audio albums management (create, delete and add audios)."
|
||||
msgstr ""
|
||||
"* Administración de albums de audio (crear, eliminar y añadir audios dentro "
|
||||
"de albums)."
|
||||
|
||||
msgid "* Post comments."
|
||||
msgstr "* Publicar comentarios."
|
||||
|
||||
msgid "* like, unlike and repost other's posts."
|
||||
msgstr ""
|
||||
"* Indicar que te gusta, que ya no te gusta o compartir publicaciones de "
|
||||
"otros usuarios."
|
||||
|
||||
msgid ""
|
||||
"* Open other's timelines so you could track someone's friends, posts or "
|
||||
"audio files."
|
||||
msgstr ""
|
||||
"* Abrir líneas temporales de otros usuarios para poder ver sus "
|
||||
"publicaciones, audios o amigos."
|
||||
|
||||
msgid "* Basic chat features."
|
||||
msgstr "* Características básicas de chat."
|
||||
|
||||
msgid ""
|
||||
"Note: When new features are added to socializer they will be added to this "
|
||||
"section."
|
||||
msgstr ""
|
||||
"Nota: Cuando sean añadidas, las nuevas características se incluirán aquí."
|
||||
|
||||
msgid "## Running"
|
||||
msgstr "## Abriendo socializer"
|
||||
|
||||
msgid ""
|
||||
"If you are using a built version, unzip the file in a new directory with no "
|
||||
"special characters, and open the socializer.exe file. If you haven't "
|
||||
"configured your VK account, you will see a dialogue, just press yes and a "
|
||||
"new dialogue will prompt for an user email or phone number and the password "
|
||||
"for your account. Take into account that the provided information will be "
|
||||
"saved in a config file as plain text. This application will need your "
|
||||
"information for renegotiating the access token when it expires."
|
||||
msgstr ""
|
||||
"Si estás usando una versión compilada (distribuible), descomprime el archivo "
|
||||
"ZIP en un nuevo directorio que no contenga caracteres especiales, y abre el "
|
||||
"archivo socializer.exe. Si no has configurado tu cuenta de VK, verás un "
|
||||
"diálogo donde se te preguntará si deseas configurar una. Si presionas en sí, "
|
||||
"podrás introducir tus datos. Toma en cuenta que la información proporcionada "
|
||||
"ha de guardarse en un archivo de configuración, como texto plano. La "
|
||||
"aplicación necesitará tu información para renovar el código de acceso cuando "
|
||||
"expire."
|
||||
|
||||
msgid ""
|
||||
"Note: Every time you grant access to socializer, probably You will receive "
|
||||
"an email from VK by telling you that someone has accessed to your account. "
|
||||
"It means that a new token has been negotiated between VK and socializer by "
|
||||
"using an authomatic process, you should ignore those advices, unless you "
|
||||
"receive an email when you are not logged in VK with socializer or other "
|
||||
"application. You can see your authorised applications in the configuration "
|
||||
"section in the VK website. New tokens are renegotiated every 24 hours."
|
||||
msgstr ""
|
||||
"Nota: Cada que se brinde acceso a socializer, probablemente recibirás un "
|
||||
"correo electrónico de VK diciéndote que puede que alguien haya entrado a tu "
|
||||
"cuenta. Significa que un nuevo código de acceso ha sido generado entre VK y "
|
||||
"Socializer mediante un proceso automático. Deberías ignorar estos avisos, a "
|
||||
"no ser que hayas recibido un correo cuando no estés usando Socializer o "
|
||||
"alguna otra aplicación. Puedes ver tus aplicaciones autorizadas en la página "
|
||||
"de tu perfil en el sitio web de VK. Un nuevo código de acceso debe ser "
|
||||
"generado cada 24 horas."
|
||||
|
||||
msgid "## Main interface"
|
||||
msgstr "## Interfaz"
|
||||
|
||||
msgid ""
|
||||
"If you have used [TWBlue](https://github.com/manuelcortez/twblue) before, "
|
||||
"the socializer's interface is quite similar. Once you have authorised your "
|
||||
"account, you will see a window with the following elements:"
|
||||
msgstr ""
|
||||
"Si alguna vez has usado [TWBlue](https//github.com/manuelcortez/twblue) "
|
||||
"anteriormente, te darás cuenta que la interfaz gráfica de socializer es muy "
|
||||
"parecida. Una vez que hayas autorizado tu cuenta, Podrás ver una ventana con "
|
||||
"los siguientes elementos:"
|
||||
|
||||
msgid ""
|
||||
"* A tree view at the left of the window, where you will see the list of "
|
||||
"buffers. These buffers are divided in three categories, posts, music and "
|
||||
"people. You could expand each category for seeing the child buffers. There "
|
||||
"are some additional buffers, timelines and chats, wich will be filled with "
|
||||
"timelines for your friends or with chats, when you start or receive a chat "
|
||||
"session."
|
||||
msgstr ""
|
||||
"* Una vista de árbol en la parte izquierda de laventana, donde podrás ver la "
|
||||
"lista de buffers. Los buffers están divididos en tres categorías, "
|
||||
"publicaciones, música y gente. Puedes expandir cada categoría para ver los "
|
||||
"elementos hijos. Hay además buffers adicionales, líneas temporales y chats, "
|
||||
"que serán usados para guardar líneas temporales para tus amigos, o chats "
|
||||
"cuando recibas o envíes un mensaje."
|
||||
|
||||
msgid "* A button for making a post to your wall."
|
||||
msgstr "* Un botón para publicar en tu muro."
|
||||
|
||||
msgid "* In audio buffers, Two buttons: Play and play all."
|
||||
msgstr ""
|
||||
"* En buffers de audio, un par de botones: Reproducir y reproducir todo."
|
||||
|
||||
msgid ""
|
||||
"* In audio album buffers, a button for loading music. By default, albums are "
|
||||
"empty, you have to press the load button for getting the album's items."
|
||||
msgstr ""
|
||||
"* En buffers para albums de audio, un botón llamado cargar álbum. De manera "
|
||||
"predeterminada, los álbumes se encuentran vacíos, debes pulsar el botón "
|
||||
"cargar álbum para descargar la información necesaria que permitirá mostrar "
|
||||
"la música dentro del buffer del álbum."
|
||||
|
||||
msgid ""
|
||||
"* A list where you will see the posts for the currently selected buffer."
|
||||
msgstr "* Una lista donde podrás ver los elementos del buffer seleccionado."
|
||||
|
||||
msgid ""
|
||||
"* In people buffers, like the friends buffer, a button for sending a message "
|
||||
"to your friends. Pressing that button will cause a chat buffer to be created."
|
||||
msgstr ""
|
||||
"* En buffers de amigos, un botón que permite enviar un mensaje a la persona "
|
||||
"seleccionada. Si es activado, el botón creará un buffer de chat "
|
||||
"automáticamente."
|
||||
|
||||
msgid ""
|
||||
"* A status bar where the program will put some useful information about what "
|
||||
"it's doing at the moment."
|
||||
msgstr ""
|
||||
"* Una barra de estado, donde el programa escribirá información importante "
|
||||
"sobre lo que se encuentra haciendo en cada momento."
|
||||
|
||||
msgid "* And a menu bar."
|
||||
msgstr "* Y una barra de menú."
|
||||
|
||||
msgid ""
|
||||
"When socializer starts, it will try to load your news items, wall, audios "
|
||||
"(your audios, recommended and populars) and friends. At the moment there are "
|
||||
"only a few supported actions for these items:"
|
||||
msgstr ""
|
||||
"Cuando socializer inicia, intentará cargar los elementos en el buffer "
|
||||
"principal, publicaciones en tu muro, canciones en tus buffers de audio (mis "
|
||||
"audios, populares y recomendaciones), así como tus amigos. Por el momento "
|
||||
"solo se pueden hacer pocas acciones para cada uno de estos tipos de elemento."
|
||||
|
||||
msgid ""
|
||||
"* Audio files: You can play the currently selected song, view the song's "
|
||||
"details (including lyrics, if available), add or remove from your library, "
|
||||
"and download it to a desired place in your hard drive. You can find audio "
|
||||
"files in your news feed or in your own audios buffers. You can find audios "
|
||||
"as post's attachments. You can create an audios timeline for displaying "
|
||||
"other's audios."
|
||||
msgstr ""
|
||||
"* Archivos de audio: Puedes reproducir el audio seleccionado, ver los "
|
||||
"detalles de la canción (incluyendo letras, si las tiene), añadirlo y "
|
||||
"eliminarlo de tu biblioteca, y descargar la canción a tu disco duro. Puedes "
|
||||
"encontrar archivos de audio en tus propios buffers de audio, en el buffer "
|
||||
"principal y pueden estar incluidos como adjuntos en publicaciones. Puedes "
|
||||
"abrir una línea temporal de audios para ver los audios de otros usuarios de "
|
||||
"VK."
|
||||
|
||||
msgid ""
|
||||
"* News feed's post: In your news feed buffer, you can press return in any "
|
||||
"post and socializer will open a new dialogue which can be different, "
|
||||
"depending in the kind of post you are when the return key was pressed. For "
|
||||
"example it will open the post if you are focusing a \"normal\" post, a list "
|
||||
"of people if you are in a post wich indicates that someone has added "
|
||||
"friends, an audio displayer if you are in a post wich indicates that someone "
|
||||
"has added an audio, etc."
|
||||
msgstr ""
|
||||
"* Publicaciones en el buffer principal: En el buffer principal, puedes "
|
||||
"pulsar la tecla intro y socializer abrirá un diálogo que puede ser "
|
||||
"diferente, dependiendo del tipo de publicación que estaba enfocada cuando se "
|
||||
"presionó la tecla. Por ejemplo, abrirá la publicación si estabas en una "
|
||||
"publicación \"normal\", una lista de personas si estabas en una publicación "
|
||||
"que indicaba que alguien había añadido amigos, el visualizador de detalles "
|
||||
"de audios si estabas en una publicación que indicaba que alguien había "
|
||||
"añadido audios, etc."
|
||||
|
||||
msgid ""
|
||||
"* Wall posts: It will show the post in a dialogue so you could interact with "
|
||||
"its attachments, view and post comments, or like/unlike/share the post."
|
||||
msgstr ""
|
||||
"* publicaciones en el muro: Mostrará la publicación en un nuevo diálogo, que "
|
||||
"te permitirá interactuar con el post, ver los adjuntos, ver y publicar "
|
||||
"comentarios, así como indicar si te gusta, ya no te gusta y compartir la "
|
||||
"publicación."
|
||||
|
||||
msgid ""
|
||||
"* You can send a message to someone by pressing the send message button in "
|
||||
"the buffer where you are, if available. Deactivated accounts cannot receive "
|
||||
"messages."
|
||||
msgstr ""
|
||||
"* Puedes enviar un mensaje a alguien pulsando el botón Enviar mensaje, si "
|
||||
"está disponible. Los usuarios con cuentas desactivadas no pueden recibir "
|
||||
"mensajes."
|
||||
|
||||
msgid "### Making a post"
|
||||
msgstr "### Haciendo una publicación"
|
||||
|
||||
msgid ""
|
||||
"When you press the post button, a new dialogue will show up. This dialogue "
|
||||
"allows you to post something in your wall. In this dialogue you have to "
|
||||
"write a message. You can translate your message and fix your spelling "
|
||||
"mistakes. Also you can post an URL address, socializer will try to add it as "
|
||||
"an attachment, so you will not have to worry about this. When you're ready, "
|
||||
"just press the send button and it'll be done."
|
||||
msgstr ""
|
||||
"Cuando pulses el botón para publicar, se mostrará un diálogo. Este diálogo "
|
||||
"te permitirá publicar algo en tu muro. En este diálogo tienes que escribir "
|
||||
"un mensaje. Puedes traducir el mensaje y corregir tus errores ortográficos. "
|
||||
"También puedes publicar una dirección URL, y socializer intentará enviarla "
|
||||
"como un adjunto a tu publicación, por lo que no tienes que preocuparte. "
|
||||
"Cuando estés listo, solo presiona el botón enviar, y estará listo."
|
||||
|
||||
msgid ""
|
||||
"If you want to add some photos, you can press the attach button, then press "
|
||||
"the kind of attachment you want to add. After this, select the file you want "
|
||||
"to add and you will see it in the list, once processed. When you are done "
|
||||
"with attachments, press the OK button, and continue with your post. When you "
|
||||
"are ready, press the send button. Your post could take some time to be "
|
||||
"published, depending in the amount of files you have added, but it should be "
|
||||
"displayed in your wall and newsfeed as soon as it is posted."
|
||||
msgstr ""
|
||||
"Si quieres añadir algunas fotos, presiona el botón adjuntar, seguidamente "
|
||||
"encuentra el botón del elemento que quieres añadir. Después, selecciona el "
|
||||
"archivo a adjuntar y lo podrás ver en la lista de archivos a cargar una vez "
|
||||
"sea procesado por el programa. Cuando hayas terminado con los adjuntos, "
|
||||
"presiona el botón aceptar, y continúa con tu publicación. Cuando esté todo "
|
||||
"listo, pulsa el botón enviar. Tu publicación podría tomar un tiempo en ser "
|
||||
"enviada, dependiendo de la cantidad y el tamaño de los adjuntos que "
|
||||
"añadiste, pero debería aparecer publicada en tu muro y en el buffer "
|
||||
"principal tan rápidamente como sea publicada."
|
||||
|
||||
msgid "### Working with posts in news feed"
|
||||
msgstr "### Trabajando con publicaciones en el buffer principal."
|
||||
|
||||
msgid ""
|
||||
"You can press the return key in any post in your news feed for opening a new "
|
||||
"dialogue with some information. The information and dialogue will be "
|
||||
"different if you are viewing a friendship's notification (when someone has "
|
||||
"added some friends), an audio file, or a regular post."
|
||||
msgstr ""
|
||||
"Puedes pulsar la tecla intro en cualquier publicación de tu buffer principal "
|
||||
"para abrir un nuevo diálogo con información. La información puede variar si "
|
||||
"estás viendo una notificación de nuevos amigos (cuando alguien añade "
|
||||
"amigos), un archivo de audio, o una publicación regular."
|
||||
|
||||
msgid ""
|
||||
"If you open a regular post in your newsfeed, you will be able to see the "
|
||||
"comments in a list, indicate if you do like or dislike the post, repost or "
|
||||
"add a new comment. If the post has some attachments, you'll find a list "
|
||||
"populated with them, you can press return in an attachment to execute its "
|
||||
"default action, wich will be different depending on the kind of attachment "
|
||||
"that you are viewing."
|
||||
msgstr ""
|
||||
"Si abres una publicación regular en tu buffer principal, serás capaz de leer "
|
||||
"los comentarios en una lista, indicar si te gusta o ya no te gusta la "
|
||||
"publicación, compartirla o añadir un nuevo comentario. Si la publicación "
|
||||
"contiene adjuntos, encontrarás una lista con ellos. Puedes pulsar intro "
|
||||
"sobre uno de ellos para abrir la acción predeterminada. La acción "
|
||||
"predeterminada para cada archivo dependerá del tipo de archivo en el que te "
|
||||
"enfoques."
|
||||
|
||||
msgid ""
|
||||
"For friend notifications, you can only view the new added friends in a list "
|
||||
"and there are some kind of posts that aren't handled. It should be improved."
|
||||
msgstr ""
|
||||
"Para las notificaciones de nuevos amigos, solo puedes ver las personas que "
|
||||
"han sido añadidas. También hay algunas publicaciones que no se muestran por "
|
||||
"defecto."
|
||||
|
||||
msgid ""
|
||||
"Additionally, you can press the menu Key or the right click for displaying "
|
||||
"a menu with some quick actions available for the post you are focusing. "
|
||||
"These actions are different for every post type."
|
||||
msgstr ""
|
||||
"Además, puedes pulsar la tecla de aplicaciones o el botón derecho del ratón "
|
||||
"para mostrar un menú de acciones rápidas que están disponibles para el "
|
||||
"elemento seleccionado. Las acciones son diferentes para cada tipo de "
|
||||
"publicación."
|
||||
|
||||
msgid "### Working with songs"
|
||||
msgstr "### Trabajando con audios"
|
||||
|
||||
msgid "Note: the following applies to audio timelines too."
|
||||
msgstr "Nota: Lo siguiente también es aplicable a líneas temporales de audio."
|
||||
|
||||
msgid ""
|
||||
"If you want to play or view audio's details, you'll have to navigate to the "
|
||||
"tree view, and, using the down arrow, look for \"my audios\", \"populars\" "
|
||||
"or \"Recommendations\". You will see two more buttons, play and play all. "
|
||||
"The play button will play the currently selected audio, and the play all "
|
||||
"button will play audios in the current buffer, starting with the current "
|
||||
"selected item. You can go to the song's list, look for a desired song and "
|
||||
"press the play button, or Ctrl+return, which is a keyboard shorcut. Take in "
|
||||
"to account that there are some keyboard shorcuts that only work in the list "
|
||||
"of items."
|
||||
msgstr ""
|
||||
"Si quieres reproducir o ver los detalles de un archivo de audio, debes "
|
||||
"navegar hasta la vista de árbol y, utilizando las flechas de cursor, ubicar "
|
||||
"algún buffer de audio (mis audios, populares o recomendaciones). Verás dos "
|
||||
"botones extras, reproducir y reproducir todo. El botón reproducir "
|
||||
"reproducirá el audio seleccionado, y el botón reproducir todo comenzará a "
|
||||
"reproducir, a partir del audio seleccionado y hasta el final, todos los "
|
||||
"audios del buffer. Puedes ir a la lista de canciones, buscar una canción que "
|
||||
"te guste y pulsar el botón reproducir, o pulsar Control intro, que es un "
|
||||
"atajo de teclado. Ten en cuenta que algunos atajos de teclado solo funcionan "
|
||||
"cuando estás en la lista de elementos."
|
||||
|
||||
msgid ""
|
||||
"You can play audio from any buffer, just press ctrl+return for making the "
|
||||
"audio playback possible."
|
||||
msgstr ""
|
||||
"Puedes reproducir audios desde cualquier buffer, solo presiona Control intro "
|
||||
"para hacer posible la reproducción."
|
||||
|
||||
msgid ""
|
||||
"If someone has added multiple audios at once to his library, you will see "
|
||||
"something like this in your newsfeed: \"(friend) has added 4 audios: audio "
|
||||
"1, audio2, audio3 and audio4\". You can press return in the post for "
|
||||
"opening the audio's details dialogue, where you will be able to see a list "
|
||||
"with these audios. By default the first detected song is selected, which "
|
||||
"means that you could read its details by pressing tab, download or add it to "
|
||||
"your library. If you change the audio in the list, the information will be "
|
||||
"updated and you will see details and actions will take effect in the new "
|
||||
"selected audio."
|
||||
msgstr ""
|
||||
"Si alguien ha añadido más de un audio a su biblioteca, podrás ver algo como "
|
||||
"lo siguiente: \"(alguien) ha añadido 4 audios: audio1, audio2, audio3 y "
|
||||
"audio4\". Puedes pulsar intro en la publicación para abrir el diálogo del "
|
||||
"visualizador de detalles de audios, donde podrás verlos todos en una lista. "
|
||||
"De forma predeterminada, el primer audio detectado está seleccionado, lo que "
|
||||
"significa que puedes pulsar tab para ver sus detalles, descargarlo y "
|
||||
"añadirlo a la biblioteca. Si cambias la canción en la lista, notarás que la "
|
||||
"información se actualizará y ahora los detalles y acciones a mostrar tendrán "
|
||||
"efecto en el nuevo audio seleccionado."
|
||||
|
||||
msgid ""
|
||||
"When an audio file is playing, you can press f5 and f6 for decreasing and "
|
||||
"increasing volume, respectively, or control+shift+return for play/pause."
|
||||
msgstr ""
|
||||
"Cuando un archivo de audio está siendo reproducido, puedes pulsar las teclas "
|
||||
"f5 y f6 para bajar y subir volumen, respectivamente. También puedes pulsar "
|
||||
"Control Shift Intro para pausar/reproducir la canción."
|
||||
|
||||
msgid ""
|
||||
"If you want to see some details for the selected audio file, you can do it "
|
||||
"by pressing the return key. You will be able to read some useful "
|
||||
"information (title, artist, duration and the lyric, if available). Also you "
|
||||
"will be able to download the song to your hard drive, you have to press the "
|
||||
"download button in the details' dialogue."
|
||||
msgstr ""
|
||||
"Si quieres ver algunos detalles para el audio seleccionado, pulsa intro "
|
||||
"sobre él. Podrás leer información importante sobre la canción (título, "
|
||||
"artista, duración y la letra, si está disponible). También podrás descargar "
|
||||
"la canción a tu disco duro, solo tienes que pulsar el botón descargar en el "
|
||||
"diálogo de detalles de audio."
|
||||
|
||||
msgid ""
|
||||
"When the download starts, you can close the details dialogue and check the "
|
||||
"status bar in the main window for seeing the current progress."
|
||||
msgstr ""
|
||||
"Cuando la descarga inicie, puedes cerrar el visualizador de detalles de "
|
||||
"audio y revisar la barra de estado para ver el progreso."
|
||||
|
||||
msgid ""
|
||||
"Additionally, you can search for audios by using the menu bar, in the buffer "
|
||||
"menu, select search, then audio. It will display a dialog where you have to "
|
||||
"set your search preferences."
|
||||
msgstr ""
|
||||
"Además, puedes hacer una búsqueda de canciones usando la barra de menú, en "
|
||||
"el menú buffer, buscar, luego audio. Mostrará un diálogo donde deberás "
|
||||
"establecer tus preferencias de búsqueda."
|
||||
|
||||
msgid ""
|
||||
"If you press the menu key, you will see a menu where you will be able to do "
|
||||
"some actions, for example, add the audio to an album, or add/remove the song "
|
||||
"from your library."
|
||||
msgstr ""
|
||||
"Si presionas la tecla de aplicaciones podrás ver un menú desde el que puedes "
|
||||
"realizar algunas acciones, por ejemplo mover la canción a un álbum, o "
|
||||
"agregarlo/eliminarlo de tu biblioteca."
|
||||
|
||||
msgid "## menu Bar"
|
||||
msgstr "## barra de menú"
|
||||
|
||||
msgid ""
|
||||
"You can go to the menu bar by pressing ALT. Right now, there are three "
|
||||
"menus, application, buffer and help:"
|
||||
msgstr ""
|
||||
"Puedes ir a la barra de menú pulsando la tecla ALT. Actualmente existen tres "
|
||||
"menús: aplicación, buffer y ayuda."
|
||||
|
||||
msgid "### Application menu"
|
||||
msgstr "### Menú aplicación"
|
||||
|
||||
msgid ""
|
||||
"* Create. Here you can create some things in VK. The only supported item at "
|
||||
"this moment is the audio album."
|
||||
msgstr ""
|
||||
"* Crear. Aquí puedes crear algunas cosas en VK. Actualmente solo se "
|
||||
"encuentra soportada la creación de álbumes de audio."
|
||||
|
||||
msgid ""
|
||||
"* Delete: Removes items from the VK servers. The only supported item here is "
|
||||
"the audio album."
|
||||
msgstr ""
|
||||
"* eliminar. Elimina elementos desde el servidor de VK. Actualmente solo se "
|
||||
"encuentra soportado el borrado de álbumes de audio."
|
||||
|
||||
msgid ""
|
||||
"* you can set your preferences by opening the preferences dialog located in "
|
||||
"this menu."
|
||||
msgstr ""
|
||||
"* Puedes establecer tus preferencias desde el diálogo de preferencias, "
|
||||
"ubicado en este menú."
|
||||
|
||||
msgid "### Buffer menu"
|
||||
msgstr "### Menú buffer"
|
||||
|
||||
msgid ""
|
||||
"* new timeline: This option allows you to create a new timeline. This kind "
|
||||
"of buffers is capable of download all posts in an user's profile."
|
||||
msgstr ""
|
||||
"* Nueva línea temporal: Esta opción permite crear una línea temporal para "
|
||||
"otro usuario de VK. Las líneas temporales pueden descargar publicaciones de "
|
||||
"otros usuarios."
|
||||
|
||||
msgid ""
|
||||
"* search: This submenu allows you to create a new buffer, at the moment, "
|
||||
"you can create only a kind of buffer, an audio search. The audio search will "
|
||||
"be located in the music category and will have the last 299 results of your "
|
||||
"query."
|
||||
msgstr ""
|
||||
"* Buscar: permite hacer una búsqueda en VK. Por el momento solo se pueden "
|
||||
"buscar archivos de audio. Las búsquedas de audio se añadirán en el buffer de "
|
||||
"música y contendrán los últimos 299 resultados."
|
||||
|
||||
msgid ""
|
||||
"* Update current buffer: perform an update operation in the selected buffer, "
|
||||
"which will retrieve the new items."
|
||||
msgstr ""
|
||||
"* Actualizar buffer: Realiza una operación de actualización en el buffer "
|
||||
"actual, lo que recuperará los nuevos elementos."
|
||||
|
||||
msgid ""
|
||||
"* Load previous items: Get the previous items for the currently focused "
|
||||
"buffer."
|
||||
msgstr ""
|
||||
"* Cargar elementos anteriores: Carga los elementos anteriormente publicados "
|
||||
"en el buffer actual."
|
||||
|
||||
msgid ""
|
||||
"* Remove buffer: Tries to remove the current buffer. Default buffers can't "
|
||||
"be removed."
|
||||
msgstr ""
|
||||
"* Eliminar buffer: Intenta remover el buffer actual. Los buffers "
|
||||
"predeterminados no pueden eliminarse."
|
||||
|
||||
msgid "The help menu is self explanatory."
|
||||
msgstr "El menú ayuda se explica por sí solo."
|
||||
|
||||
msgid "## Contributing"
|
||||
msgstr "## Contribuir"
|
||||
|
||||
msgid ""
|
||||
"If you notice some errors in this document, or features that are not "
|
||||
"documented yet, you can suggest those changes by contacting me (more "
|
||||
"information can be find in the following section)."
|
||||
msgstr ""
|
||||
"Si notas algún error en este documento, alguna sección no cubierta o "
|
||||
"simplemente quieres sugerir algo, puedes hacerlo mediante las formas de "
|
||||
"contacto (lee la siguiente sección)."
|
||||
|
||||
msgid "## contact"
|
||||
msgstr "## Contacto"
|
||||
|
||||
msgid ""
|
||||
"If you have questions, don't esitate to contact me in [Twitter,](https://"
|
||||
"twitter.com/manuelcortez00) or sending me an email to "
|
||||
"manuel(at)manuelcortez(dot)net. Just replace the words in parentheses with "
|
||||
"the original signs."
|
||||
msgstr ""
|
||||
"Si tienes preguntas, no dudes en contactarme mediante [Twitter,](https://"
|
||||
"twitter.com/manuelcortez00) o envíame un correo electrónico a "
|
||||
"manuel(arroba)manuelcortez(punto)net. Solo asegúrate de remplazar las "
|
||||
"palabras entre paréntesis por el símbolo original."
|
105
doc/manual.md
Normal file
105
doc/manual.md
Normal file
@@ -0,0 +1,105 @@
|
||||
socializer's manual
|
||||
|
||||
## Introduction
|
||||
|
||||
Socializer is an application to use [VK.com](https://vk.com) in an easy and accessible way with minimal CPU resource usage. Socializer will allow you to interact with the VK social network by giving you access to the most relevant features such as:
|
||||
|
||||
* Basic post creation in your wall (including photos).
|
||||
* Audio addition, removal, download and search.
|
||||
* audio albums management (create, delete and add audios).
|
||||
* Post comments.
|
||||
* like, unlike and repost other's posts.
|
||||
* Open other's timelines so you could track someone's friends, posts or audio files.
|
||||
* Basic chat features.
|
||||
|
||||
Note: When new features are added to socializer they will be added to this section.
|
||||
|
||||
## Running
|
||||
|
||||
If you are using a built version, unzip the file in a new directory with no special characters, and open the socializer.exe file. If you haven't configured your VK account, you will see a dialogue, just press yes and a new dialogue will prompt for an user email or phone number and the password for your account. Take into account that the provided information will be saved in a config file as plain text. This application will need your information for renegotiating the access token when it expires.
|
||||
|
||||
Note: Every time you grant access to socializer, probably You will receive an email from VK by telling you that someone has accessed to your account. It means that a new token has been negotiated between VK and socializer by using an authomatic process, you should ignore those advices, unless you receive an email when you are not logged in VK with socializer or other application. You can see your authorised applications in the configuration section in the VK website. New tokens are renegotiated every 24 hours.
|
||||
|
||||
## Main interface
|
||||
|
||||
If you have used [TWBlue](https://github.com/manuelcortez/twblue) before, the socializer's interface is quite similar. Once you have authorised your account, you will see a window with the following elements:
|
||||
|
||||
* A tree view at the left of the window, where you will see the list of buffers. These buffers are divided in three categories, posts, music and people. You could expand each category for seeing the child buffers. There are some additional buffers, timelines and chats, wich will be filled with timelines for your friends or with chats, when you start or receive a chat session.
|
||||
* A button for making a post to your wall.
|
||||
* In audio buffers, Two buttons: Play and play all.
|
||||
* In audio album buffers, a button for loading music. By default, albums are empty, you have to press the load button for getting the album's items.
|
||||
* A list where you will see the posts for the currently selected buffer.
|
||||
* In people buffers, like the friends buffer, a button for sending a message to your friends. Pressing that button will cause a chat buffer to be created.
|
||||
* A status bar where the program will put some useful information about what it's doing at the moment.
|
||||
* And a menu bar.
|
||||
|
||||
When socializer starts, it will try to load your news items, wall, audios (your audios, recommended and populars) and friends. At the moment there are only a few supported actions for these items:
|
||||
|
||||
* Audio files: You can play the currently selected song, view the song's details (including lyrics, if available), add or remove from your library, and download it to a desired place in your hard drive. You can find audio files in your news feed or in your own audios buffers. You can find audios as post's attachments. You can create an audios timeline for displaying other's audios.
|
||||
* News feed's post: In your news feed buffer, you can press return in any post and socializer will open a new dialogue which can be different, depending in the kind of post you are when the return key was pressed. For example it will open the post if you are focusing a "normal" post, a list of people if you are in a post wich indicates that someone has added friends, an audio displayer if you are in a post wich indicates that someone has added an audio, etc.
|
||||
* Wall posts: It will show the post in a dialogue so you could interact with its attachments, view and post comments, or like/unlike/share the post.
|
||||
* You can send a message to someone by pressing the send message button in the buffer where you are, if available. Deactivated accounts cannot receive messages.
|
||||
|
||||
### Making a post
|
||||
|
||||
When you press the post button, a new dialogue will show up. This dialogue allows you to post something in your wall. In this dialogue you have to write a message. You can translate your message and fix your spelling mistakes. Also you can post an URL address, socializer will try to add it as an attachment, so you will not have to worry about this. When you're ready, just press the send button and it'll be done.
|
||||
|
||||
If you want to add some photos, you can press the attach button, then press the kind of attachment you want to add. After this, select the file you want to add and you will see it in the list, once processed. When you are done with attachments, press the OK button, and continue with your post. When you are ready, press the send button. Your post could take some time to be published, depending in the amount of files you have added, but it should be displayed in your wall and newsfeed as soon as it is posted.
|
||||
|
||||
### Working with posts in news feed
|
||||
|
||||
You can press the return key in any post in your news feed for opening a new dialogue with some information. The information and dialogue will be different if you are viewing a friendship's notification (when someone has added some friends), an audio file, or a regular post.
|
||||
|
||||
If you open a regular post in your newsfeed, you will be able to see the comments in a list, indicate if you do like or dislike the post, repost or add a new comment. If the post has some attachments, you'll find a list populated with them, you can press return in an attachment to execute its default action, wich will be different depending on the kind of attachment that you are viewing.
|
||||
|
||||
For friend notifications, you can only view the new added friends in a list and there are some kind of posts that aren't handled. It should be improved.
|
||||
|
||||
Additionally, you can press the menu Key or the right click for displaying a menu with some quick actions available for the post you are focusing. These actions are different for every post type.
|
||||
|
||||
### Working with songs
|
||||
|
||||
Note: the following applies to audio timelines too.
|
||||
|
||||
If you want to play or view audio's details, you'll have to navigate to the tree view, and, using the down arrow, look for "my audios", "populars" or "Recommendations". You will see two more buttons, play and play all. The play button will play the currently selected audio, and the play all button will play audios in the current buffer, starting with the current selected item. You can go to the song's list, look for a desired song and press the play button, or Ctrl+return, which is a keyboard shorcut. Take in to account that there are some keyboard shorcuts that only work in the list of items.
|
||||
|
||||
You can play audio from any buffer, just press ctrl+return for making the audio playback possible.
|
||||
|
||||
If someone has added multiple audios at once to his library, you will see something like this in your newsfeed: "(friend) has added 4 audios: audio 1, audio2, audio3 and audio4". You can press return in the post for opening the audio's details dialogue, where you will be able to see a list with these audios. By default the first detected song is selected, which means that you could read its details by pressing tab, download or add it to your library. If you change the audio in the list, the information will be updated and you will see details and actions will take effect in the new selected audio.
|
||||
|
||||
When an audio file is playing, you can press f5 and f6 for decreasing and increasing volume, respectively, or control+shift+return for play/pause.
|
||||
|
||||
If you want to see some details for the selected audio file, you can do it by pressing the return key. You will be able to read some useful information (title, artist, duration and the lyric, if available). Also you will be able to download the song to your hard drive, you have to press the download button in the details' dialogue.
|
||||
|
||||
When the download starts, you can close the details dialogue and check the status bar in the main window for seeing the current progress.
|
||||
|
||||
Additionally, you can search for audios by using the menu bar, in the buffer menu, select search, then audio. It will display a dialog where you have to set your search preferences.
|
||||
|
||||
If you press the menu key, you will see a menu where you will be able to do some actions, for example, add the audio to an album, or add/remove the song from your library.
|
||||
|
||||
## menu Bar
|
||||
|
||||
You can go to the menu bar by pressing ALT. Right now, there are three menus, application, buffer and help:
|
||||
|
||||
### Application menu
|
||||
|
||||
* Create. Here you can create some things in VK. The only supported item at this moment is the audio album.
|
||||
* Delete: Removes items from the VK servers. The only supported item here is the audio album.
|
||||
* you can set your preferences by opening the preferences dialog located in this menu.
|
||||
|
||||
### Buffer menu
|
||||
|
||||
* new timeline: This option allows you to create a new timeline. This kind of buffers is capable of download all posts in an user's profile.
|
||||
* search: This submenu allows you to create a new buffer, at the moment, you can create only a kind of buffer, an audio search. The audio search will be located in the music category and will have the last 299 results of your query.
|
||||
* Update current buffer: perform an update operation in the selected buffer, which will retrieve the new items.
|
||||
* Load previous items: Get the previous items for the currently focused buffer.
|
||||
* Remove buffer: Tries to remove the current buffer. Default buffers can't be removed.
|
||||
|
||||
The help menu is self explanatory.
|
||||
|
||||
## Contributing
|
||||
|
||||
If you notice some errors in this document, or features that are not documented yet, you can suggest those changes by contacting me (more information can be find in the following section).
|
||||
|
||||
## contact
|
||||
|
||||
If you have questions, don't esitate to contact me in [Twitter,](https://twitter.com/manuelcortez00) or sending me an email to manuel(at)manuelcortez(dot)net. Just replace the words in parentheses with the original signs.
|
67
doc/strings.py
Normal file
67
doc/strings.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
documentation = [
|
||||
_(u"""socializer's manual """),
|
||||
"",_(u"""## Introduction"""),
|
||||
"",_(u"""Socializer is an application to use [VK.com](https://vk.com) in an easy and accessible way with minimal CPU resource usage. Socializer will allow you to interact with the VK social network by giving you access to the most relevant features such as:"""),
|
||||
"",_(u"""* Basic post creation in your wall (including photos)."""),
|
||||
_(u"""* Audio addition, removal, download and search."""),
|
||||
_(u"""* audio albums management (create, delete and add audios)."""),
|
||||
_(u"""* Post comments."""),
|
||||
_(u"""* like, unlike and repost other's posts."""),
|
||||
_(u"""* Open other's timelines so you could track someone's friends, posts or audio files."""),
|
||||
_(u"""* Basic chat features."""),
|
||||
"",_(u"""Note: When new features are added to socializer they will be added to this section."""),
|
||||
"",_(u"""## Running"""),
|
||||
"",_(u"""If you are using a built version, unzip the file in a new directory with no special characters, and open the socializer.exe file. If you haven't configured your VK account, you will see a dialogue, just press yes and a new dialogue will prompt for an user email or phone number and the password for your account. Take into account that the provided information will be saved in a config file as plain text. This application will need your information for renegotiating the access token when it expires."""),
|
||||
"",_(u"""Note: Every time you grant access to socializer, probably You will receive an email from VK by telling you that someone has accessed to your account. It means that a new token has been negotiated between VK and socializer by using an authomatic process, you should ignore those advices, unless you receive an email when you are not logged in VK with socializer or other application. You can see your authorised applications in the configuration section in the VK website. New tokens are renegotiated every 24 hours."""),
|
||||
"",_(u"""## Main interface"""),
|
||||
"",_(u"""If you have used [TWBlue](https://github.com/manuelcortez/twblue) before, the socializer's interface is quite similar. Once you have authorised your account, you will see a window with the following elements:"""),
|
||||
"",_(u"""* A tree view at the left of the window, where you will see the list of buffers. These buffers are divided in three categories, posts, music and people. You could expand each category for seeing the child buffers. There are some additional buffers, timelines and chats, wich will be filled with timelines for your friends or with chats, when you start or receive a chat session."""),
|
||||
_(u"""* A button for making a post to your wall."""),
|
||||
_(u"""* In audio buffers, Two buttons: Play and play all."""),
|
||||
_(u"""* In audio album buffers, a button for loading music. By default, albums are empty, you have to press the load button for getting the album's items."""),
|
||||
_(u"""* A list where you will see the posts for the currently selected buffer."""),
|
||||
_(u"""* In people buffers, like the friends buffer, a button for sending a message to your friends. Pressing that button will cause a chat buffer to be created."""),
|
||||
_(u"""* A status bar where the program will put some useful information about what it's doing at the moment."""),
|
||||
_(u"""* And a menu bar."""),
|
||||
"",_(u"""When socializer starts, it will try to load your news items, wall, audios (your audios, recommended and populars) and friends. At the moment there are only a few supported actions for these items:"""),
|
||||
"",_(u"""* Audio files: You can play the currently selected song, view the song's details (including lyrics, if available), add or remove from your library, and download it to a desired place in your hard drive. You can find audio files in your news feed or in your own audios buffers. You can find audios as post's attachments. You can create an audios timeline for displaying other's audios."""),
|
||||
_(u"""* News feed's post: In your news feed buffer, you can press return in any post and socializer will open a new dialogue which can be different, depending in the kind of post you are when the return key was pressed. For example it will open the post if you are focusing a "normal" post, a list of people if you are in a post wich indicates that someone has added friends, an audio displayer if you are in a post wich indicates that someone has added an audio, etc."""),
|
||||
_(u"""* Wall posts: It will show the post in a dialogue so you could interact with its attachments, view and post comments, or like/unlike/share the post."""),
|
||||
_(u"""* You can send a message to someone by pressing the send message button in the buffer where you are, if available. Deactivated accounts cannot receive messages."""),
|
||||
"",_(u"""### Making a post"""),
|
||||
"",_(u"""When you press the post button, a new dialogue will show up. This dialogue allows you to post something in your wall. In this dialogue you have to write a message. You can translate your message and fix your spelling mistakes. Also you can post an URL address, socializer will try to add it as an attachment, so you will not have to worry about this. When you're ready, just press the send button and it'll be done."""),
|
||||
"",_(u"""If you want to add some photos, you can press the attach button, then press the kind of attachment you want to add. After this, select the file you want to add and you will see it in the list, once processed. When you are done with attachments, press the OK button, and continue with your post. When you are ready, press the send button. Your post could take some time to be published, depending in the amount of files you have added, but it should be displayed in your wall and newsfeed as soon as it is posted."""),
|
||||
"",_(u"""### Working with posts in news feed"""),
|
||||
"",_(u"""You can press the return key in any post in your news feed for opening a new dialogue with some information. The information and dialogue will be different if you are viewing a friendship's notification (when someone has added some friends), an audio file, or a regular post."""),
|
||||
"",_(u"""If you open a regular post in your newsfeed, you will be able to see the comments in a list, indicate if you do like or dislike the post, repost or add a new comment. If the post has some attachments, you'll find a list populated with them, you can press return in an attachment to execute its default action, wich will be different depending on the kind of attachment that you are viewing."""),
|
||||
"",_(u"""For friend notifications, you can only view the new added friends in a list and there are some kind of posts that aren't handled. It should be improved."""),
|
||||
"",_(u"""Additionally, you can press the menu Key or the right click for displaying a menu with some quick actions available for the post you are focusing. These actions are different for every post type."""),
|
||||
"",_(u"""### Working with songs"""),
|
||||
"",_(u"""Note: the following applies to audio timelines too."""),
|
||||
"",_(u"""If you want to play or view audio's details, you'll have to navigate to the tree view, and, using the down arrow, look for "my audios", "populars" or "Recommendations". You will see two more buttons, play and play all. The play button will play the currently selected audio, and the play all button will play audios in the current buffer, starting with the current selected item. You can go to the song's list, look for a desired song and press the play button, or Ctrl+return, which is a keyboard shorcut. Take in to account that there are some keyboard shorcuts that only work in the list of items."""),
|
||||
"",_(u"""You can play audio from any buffer, just press ctrl+return for making the audio playback possible."""),
|
||||
"",_(u"""If someone has added multiple audios at once to his library, you will see something like this in your newsfeed: "(friend) has added 4 audios: audio 1, audio2, audio3 and audio4". You can press return in the post for opening the audio's details dialogue, where you will be able to see a list with these audios. By default the first detected song is selected, which means that you could read its details by pressing tab, download or add it to your library. If you change the audio in the list, the information will be updated and you will see details and actions will take effect in the new selected audio."""),
|
||||
"",_(u"""When an audio file is playing, you can press f5 and f6 for decreasing and increasing volume, respectively, or control+shift+return for play/pause."""),
|
||||
"",_(u"""If you want to see some details for the selected audio file, you can do it by pressing the return key. You will be able to read some useful information (title, artist, duration and the lyric, if available). Also you will be able to download the song to your hard drive, you have to press the download button in the details' dialogue."""),
|
||||
"",_(u"""When the download starts, you can close the details dialogue and check the status bar in the main window for seeing the current progress."""),
|
||||
"",_(u"""Additionally, you can search for audios by using the menu bar, in the buffer menu, select search, then audio. It will display a dialog where you have to set your search preferences."""),
|
||||
"",_(u"""If you press the menu key, you will see a menu where you will be able to do some actions, for example, add the audio to an album, or add/remove the song from your library."""),
|
||||
"",_(u"""## menu Bar"""),
|
||||
"",_(u"""You can go to the menu bar by pressing ALT. Right now, there are three menus, application, buffer and help:"""),
|
||||
"",_(u"""### Application menu"""),
|
||||
"",_(u"""* Create. Here you can create some things in VK. The only supported item at this moment is the audio album."""),
|
||||
_(u"""* Delete: Removes items from the VK servers. The only supported item here is the audio album."""),
|
||||
_(u"""* you can set your preferences by opening the preferences dialog located in this menu."""),
|
||||
"",_(u"""### Buffer menu"""),
|
||||
"",_(u"""* new timeline: This option allows you to create a new timeline. This kind of buffers is capable of download all posts in an user's profile."""),
|
||||
_(u"""* search: This submenu allows you to create a new buffer, at the moment, you can create only a kind of buffer, an audio search. The audio search will be located in the music category and will have the last 299 results of your query."""),
|
||||
_(u"""* Update current buffer: perform an update operation in the selected buffer, which will retrieve the new items."""),
|
||||
_(u"""* Load previous items: Get the previous items for the currently focused buffer."""),
|
||||
_(u"""* Remove buffer: Tries to remove the current buffer. Default buffers can't be removed."""),
|
||||
"",_(u"""The help menu is self explanatory."""),
|
||||
"",_(u"""## Contributing"""),
|
||||
"",_(u"""If you notice some errors in this document, or features that are not documented yet, you can suggest those changes by contacting me (more information can be find in the following section)."""),
|
||||
"",_(u"""## contact"""),
|
||||
"",_(u"""If you have questions, don't esitate to contact me in [Twitter,](https://twitter.com/manuelcortez00) or sending me an email to manuel(at)manuelcortez(dot)net. Just replace the words in parentheses with the original signs."""),
|
||||
]
|
Binary file not shown.
@@ -46,6 +46,11 @@ cd documentation
|
||||
$pandocpath -s changelog.md -o changelog.html
|
||||
rm changelog.md
|
||||
cd ..
|
||||
cd ../doc
|
||||
$pythonpath32/python.exe generator.py
|
||||
mv -f en ../src/documentation/
|
||||
mv -f es ../src/documentation/
|
||||
cd ../src
|
||||
$pythonpath32/python.exe "setup.py" "py2exe" "--quiet"
|
||||
mv -f dist ../nightly/socializer
|
||||
rm -rf build
|
||||
|
@@ -1,3 +0,0 @@
|
||||
@echo off
|
||||
echo Generating application translation strings...
|
||||
C:\python27x86\python.exe pygettext.py -v -d socializer ../src/*.pyw ../src/*.py ../src/*/*.py ../src/*/*.pyw ../src/*/*/*.py ../src/*/*/*.pyw ../src/*/*/*/*.py ../src/*/*/*/*.pyw ../src/*/*/*/*/*.py ../src/*/*/*/*/*.pyw
|
7
scripts/genpot_doc.bat
Normal file
7
scripts/genpot_doc.bat
Normal file
@@ -0,0 +1,7 @@
|
||||
@echo off
|
||||
echo Generating file list..
|
||||
dir ..\doc\*.py /L /B /S > %TEMP%\listfile.txt
|
||||
echo Generating .POT file...
|
||||
xgettext --language=Python -o socializer-documentation.pot --keyword=_ -d socializer -f %TEMP%\listfile.txt -c --no-location --no-wrap
|
||||
del %TEMP%\listfile.txt
|
||||
echo Done.
|
7
scripts/genpot_interface.bat
Normal file
7
scripts/genpot_interface.bat
Normal file
@@ -0,0 +1,7 @@
|
||||
@echo off
|
||||
echo Generating file list..
|
||||
dir ..\src\*.py /L /B /S > %TEMP%\listfile.txt
|
||||
echo Generating .POT file...
|
||||
xgettext --language=Python -o socializer.pot --keyword=_ -d socializer -f %TEMP%\listfile.txt -c --no-location --no-wrap
|
||||
del %TEMP%\listfile.txt
|
||||
echo Done.
|
213
scripts/socializer-documentation.pot
Normal file
213
scripts/socializer-documentation.pot
Normal file
@@ -0,0 +1,213 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-06-29 13:33-0500\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#. Translators: the label for the Windows default NVDA interface language.
|
||||
msgid "User default"
|
||||
msgstr ""
|
||||
|
||||
msgid "socializer's manual "
|
||||
msgstr ""
|
||||
|
||||
msgid "## Introduction"
|
||||
msgstr ""
|
||||
|
||||
msgid "Socializer is an application to use [VK.com](https://vk.com) in an easy and accessible way with minimal CPU resource usage. Socializer will allow you to interact with the VK social network by giving you access to the most relevant features such as:"
|
||||
msgstr ""
|
||||
|
||||
msgid "* Basic post creation in your wall (including photos)."
|
||||
msgstr ""
|
||||
|
||||
msgid "* Audio addition, removal, download and search."
|
||||
msgstr ""
|
||||
|
||||
msgid "* audio albums management (create, delete and add audios)."
|
||||
msgstr ""
|
||||
|
||||
msgid "* Post comments."
|
||||
msgstr ""
|
||||
|
||||
msgid "* like, unlike and repost other's posts."
|
||||
msgstr ""
|
||||
|
||||
msgid "* Open other's timelines so you could track someone's friends, posts or audio files."
|
||||
msgstr ""
|
||||
|
||||
msgid "* Basic chat features."
|
||||
msgstr ""
|
||||
|
||||
msgid "Note: When new features are added to socializer they will be added to this section."
|
||||
msgstr ""
|
||||
|
||||
msgid "## Running"
|
||||
msgstr ""
|
||||
|
||||
msgid "If you are using a built version, unzip the file in a new directory with no special characters, and open the socializer.exe file. If you haven't configured your VK account, you will see a dialogue, just press yes and a new dialogue will prompt for an user email or phone number and the password for your account. Take into account that the provided information will be saved in a config file as plain text. This application will need your information for renegotiating the access token when it expires."
|
||||
msgstr ""
|
||||
|
||||
msgid "Note: Every time you grant access to socializer, probably You will receive an email from VK by telling you that someone has accessed to your account. It means that a new token has been negotiated between VK and socializer by using an authomatic process, you should ignore those advices, unless you receive an email when you are not logged in VK with socializer or other application. You can see your authorised applications in the configuration section in the VK website. New tokens are renegotiated every 24 hours."
|
||||
msgstr ""
|
||||
|
||||
msgid "## Main interface"
|
||||
msgstr ""
|
||||
|
||||
msgid "If you have used [TWBlue](https://github.com/manuelcortez/twblue) before, the socializer's interface is quite similar. Once you have authorised your account, you will see a window with the following elements:"
|
||||
msgstr ""
|
||||
|
||||
msgid "* A tree view at the left of the window, where you will see the list of buffers. These buffers are divided in three categories, posts, music and people. You could expand each category for seeing the child buffers. There are some additional buffers, timelines and chats, wich will be filled with timelines for your friends or with chats, when you start or receive a chat session."
|
||||
msgstr ""
|
||||
|
||||
msgid "* A button for making a post to your wall."
|
||||
msgstr ""
|
||||
|
||||
msgid "* In audio buffers, Two buttons: Play and play all."
|
||||
msgstr ""
|
||||
|
||||
msgid "* In audio album buffers, a button for loading music. By default, albums are empty, you have to press the load button for getting the album's items."
|
||||
msgstr ""
|
||||
|
||||
msgid "* A list where you will see the posts for the currently selected buffer."
|
||||
msgstr ""
|
||||
|
||||
msgid "* In people buffers, like the friends buffer, a button for sending a message to your friends. Pressing that button will cause a chat buffer to be created."
|
||||
msgstr ""
|
||||
|
||||
msgid "* A status bar where the program will put some useful information about what it's doing at the moment."
|
||||
msgstr ""
|
||||
|
||||
msgid "* And a menu bar."
|
||||
msgstr ""
|
||||
|
||||
msgid "When socializer starts, it will try to load your news items, wall, audios (your audios, recommended and populars) and friends. At the moment there are only a few supported actions for these items:"
|
||||
msgstr ""
|
||||
|
||||
msgid "* Audio files: You can play the currently selected song, view the song's details (including lyrics, if available), add or remove from your library, and download it to a desired place in your hard drive. You can find audio files in your news feed or in your own audios buffers. You can find audios as post's attachments. You can create an audios timeline for displaying other's audios."
|
||||
msgstr ""
|
||||
|
||||
msgid "* News feed's post: In your news feed buffer, you can press return in any post and socializer will open a new dialogue which can be different, depending in the kind of post you are when the return key was pressed. For example it will open the post if you are focusing a \"normal\" post, a list of people if you are in a post wich indicates that someone has added friends, an audio displayer if you are in a post wich indicates that someone has added an audio, etc."
|
||||
msgstr ""
|
||||
|
||||
msgid "* Wall posts: It will show the post in a dialogue so you could interact with its attachments, view and post comments, or like/unlike/share the post."
|
||||
msgstr ""
|
||||
|
||||
msgid "* You can send a message to someone by pressing the send message button in the buffer where you are, if available. Deactivated accounts cannot receive messages."
|
||||
msgstr ""
|
||||
|
||||
msgid "### Making a post"
|
||||
msgstr ""
|
||||
|
||||
msgid "When you press the post button, a new dialogue will show up. This dialogue allows you to post something in your wall. In this dialogue you have to write a message. You can translate your message and fix your spelling mistakes. Also you can post an URL address, socializer will try to add it as an attachment, so you will not have to worry about this. When you're ready, just press the send button and it'll be done."
|
||||
msgstr ""
|
||||
|
||||
msgid "If you want to add some photos, you can press the attach button, then press the kind of attachment you want to add. After this, select the file you want to add and you will see it in the list, once processed. When you are done with attachments, press the OK button, and continue with your post. When you are ready, press the send button. Your post could take some time to be published, depending in the amount of files you have added, but it should be displayed in your wall and newsfeed as soon as it is posted."
|
||||
msgstr ""
|
||||
|
||||
msgid "### Working with posts in news feed"
|
||||
msgstr ""
|
||||
|
||||
msgid "You can press the return key in any post in your news feed for opening a new dialogue with some information. The information and dialogue will be different if you are viewing a friendship's notification (when someone has added some friends), an audio file, or a regular post."
|
||||
msgstr ""
|
||||
|
||||
msgid "If you open a regular post in your newsfeed, you will be able to see the comments in a list, indicate if you do like or dislike the post, repost or add a new comment. If the post has some attachments, you'll find a list populated with them, you can press return in an attachment to execute its default action, wich will be different depending on the kind of attachment that you are viewing."
|
||||
msgstr ""
|
||||
|
||||
msgid "For friend notifications, you can only view the new added friends in a list and there are some kind of posts that aren't handled. It should be improved."
|
||||
msgstr ""
|
||||
|
||||
msgid "Additionally, you can press the menu Key or the right click for displaying a menu with some quick actions available for the post you are focusing. These actions are different for every post type."
|
||||
msgstr ""
|
||||
|
||||
msgid "### Working with songs"
|
||||
msgstr ""
|
||||
|
||||
msgid "Note: the following applies to audio timelines too."
|
||||
msgstr ""
|
||||
|
||||
msgid "If you want to play or view audio's details, you'll have to navigate to the tree view, and, using the down arrow, look for \"my audios\", \"populars\" or \"Recommendations\". You will see two more buttons, play and play all. The play button will play the currently selected audio, and the play all button will play audios in the current buffer, starting with the current selected item. You can go to the song's list, look for a desired song and press the play button, or Ctrl+return, which is a keyboard shorcut. Take in to account that there are some keyboard shorcuts that only work in the list of items."
|
||||
msgstr ""
|
||||
|
||||
msgid "You can play audio from any buffer, just press ctrl+return for making the audio playback possible."
|
||||
msgstr ""
|
||||
|
||||
msgid "If someone has added multiple audios at once to his library, you will see something like this in your newsfeed: \"(friend) has added 4 audios: audio 1, audio2, audio3 and audio4\". You can press return in the post for opening the audio's details dialogue, where you will be able to see a list with these audios. By default the first detected song is selected, which means that you could read its details by pressing tab, download or add it to your library. If you change the audio in the list, the information will be updated and you will see details and actions will take effect in the new selected audio."
|
||||
msgstr ""
|
||||
|
||||
msgid "When an audio file is playing, you can press f5 and f6 for decreasing and increasing volume, respectively, or control+shift+return for play/pause."
|
||||
msgstr ""
|
||||
|
||||
msgid "If you want to see some details for the selected audio file, you can do it by pressing the return key. You will be able to read some useful information (title, artist, duration and the lyric, if available). Also you will be able to download the song to your hard drive, you have to press the download button in the details' dialogue."
|
||||
msgstr ""
|
||||
|
||||
msgid "When the download starts, you can close the details dialogue and check the status bar in the main window for seeing the current progress."
|
||||
msgstr ""
|
||||
|
||||
msgid "Additionally, you can search for audios by using the menu bar, in the buffer menu, select search, then audio. It will display a dialog where you have to set your search preferences."
|
||||
msgstr ""
|
||||
|
||||
msgid "If you press the menu key, you will see a menu where you will be able to do some actions, for example, add the audio to an album, or add/remove the song from your library."
|
||||
msgstr ""
|
||||
|
||||
msgid "## menu Bar"
|
||||
msgstr ""
|
||||
|
||||
msgid "You can go to the menu bar by pressing ALT. Right now, there are three menus, application, buffer and help:"
|
||||
msgstr ""
|
||||
|
||||
msgid "### Application menu"
|
||||
msgstr ""
|
||||
|
||||
msgid "* Create. Here you can create some things in VK. The only supported item at this moment is the audio album."
|
||||
msgstr ""
|
||||
|
||||
msgid "* Delete: Removes items from the VK servers. The only supported item here is the audio album."
|
||||
msgstr ""
|
||||
|
||||
msgid "* you can set your preferences by opening the preferences dialog located in this menu."
|
||||
msgstr ""
|
||||
|
||||
msgid "### Buffer menu"
|
||||
msgstr ""
|
||||
|
||||
msgid "* new timeline: This option allows you to create a new timeline. This kind of buffers is capable of download all posts in an user's profile."
|
||||
msgstr ""
|
||||
|
||||
msgid "* search: This submenu allows you to create a new buffer, at the moment, you can create only a kind of buffer, an audio search. The audio search will be located in the music category and will have the last 299 results of your query."
|
||||
msgstr ""
|
||||
|
||||
msgid "* Update current buffer: perform an update operation in the selected buffer, which will retrieve the new items."
|
||||
msgstr ""
|
||||
|
||||
msgid "* Load previous items: Get the previous items for the currently focused buffer."
|
||||
msgstr ""
|
||||
|
||||
msgid "* Remove buffer: Tries to remove the current buffer. Default buffers can't be removed."
|
||||
msgstr ""
|
||||
|
||||
msgid "The help menu is self explanatory."
|
||||
msgstr ""
|
||||
|
||||
msgid "## Contributing"
|
||||
msgstr ""
|
||||
|
||||
msgid "If you notice some errors in this document, or features that are not documented yet, you can suggest those changes by contacting me (more information can be find in the following section)."
|
||||
msgstr ""
|
||||
|
||||
msgid "## contact"
|
||||
msgstr ""
|
||||
|
||||
msgid "If you have questions, don't esitate to contact me in [Twitter,](https://twitter.com/manuelcortez00) or sending me an email to manuel(at)manuelcortez(dot)net. Just replace the words in parentheses with the original signs."
|
||||
msgstr ""
|
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
name = "Socializer"
|
||||
version = "0.13"
|
||||
version = "0.14"
|
||||
author = u"Manuel Cortéz"
|
||||
authorEmail = "manuel@manuelcortez.net"
|
||||
copyright = u"Copyright (C) 2016, Manuel cortéz."
|
||||
|
@@ -20,6 +20,7 @@ class attach(object):
|
||||
imageInfo = {"type": "photo", "file": image, "description": os.path.basename(image)}
|
||||
log.debug("Image data to upload: %r" % (imageInfo,))
|
||||
self.attachments.append(imageInfo)
|
||||
# Translators: This is the text displayed in the attachments dialog, when the user adds a photo.
|
||||
info = [_(u"Photo"), os.path.basename(image)]
|
||||
self.dialog.attachments.insert_item(False, *info)
|
||||
self.dialog.remove.Enable(True)
|
||||
|
@@ -1,4 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import languageHandler
|
||||
import arrow
|
||||
import wx
|
||||
import widgetUtils
|
||||
import messages
|
||||
@@ -7,11 +9,12 @@ import posts
|
||||
import player
|
||||
import output
|
||||
import logging
|
||||
import selector
|
||||
from wxUI.tabs import home
|
||||
from pubsub import pub
|
||||
from sessionmanager import session
|
||||
from mysc.thread_utils import call_threaded
|
||||
from wxUI import commonMessages
|
||||
from wxUI import commonMessages, menus
|
||||
from vk import upload
|
||||
from vk.exceptions import VkAPIMethodError
|
||||
|
||||
@@ -19,6 +22,10 @@ log = logging.getLogger("controller.buffers")
|
||||
|
||||
class baseBuffer(object):
|
||||
""" a basic representation of a buffer. Other buffers should be derived from this class"""
|
||||
|
||||
def get_post(self):
|
||||
return self.session.db[self.name]["items"][self.tab.list.get_selected()]
|
||||
|
||||
def __init__(self, parent=None, name="", session=None, composefunc=None, *args, **kwargs):
|
||||
""" parent wx.Treebook: parent for the buffer panel,
|
||||
name str: Name for saving this buffer's data in the local storage variable,
|
||||
@@ -36,6 +43,9 @@ class baseBuffer(object):
|
||||
self.update_function = "get_page"
|
||||
self.name = name
|
||||
self.connect_events()
|
||||
self.user_key = "source_id"
|
||||
self.post_key = "post_id"
|
||||
self.can_get_items = True
|
||||
|
||||
def create_tab(self, parent):
|
||||
""" Creates the Wx panel."""
|
||||
@@ -50,6 +60,7 @@ class baseBuffer(object):
|
||||
""" Retrieves items from the VK API. This function is called repeatedly by the main controller and users could call it implicitly as well with the update buffer option.
|
||||
show_nextpage boolean: If it's true, it will try to load previous results.
|
||||
"""
|
||||
if self.can_get_items == False: return
|
||||
retrieved = True # Control variable for handling unauthorised/connection errors.
|
||||
try:
|
||||
num = getattr(self.session, "get_newsfeed")(show_nextpage=show_nextpage, name=self.name, *self.args, **self.kwargs)
|
||||
@@ -111,6 +122,80 @@ class baseBuffer(object):
|
||||
def connect_events(self):
|
||||
widgetUtils.connect_event(self.tab.post, widgetUtils.BUTTON_PRESSED, self.post)
|
||||
widgetUtils.connect_event(self.tab.list.list, widgetUtils.KEYPRESS, self.get_event)
|
||||
widgetUtils.connect_event(self.tab.list.list, wx.EVT_LIST_ITEM_RIGHT_CLICK, self.show_menu)
|
||||
widgetUtils.connect_event(self.tab.list.list, wx.EVT_LIST_KEY_DOWN, self.show_menu_by_key)
|
||||
self.tab.set_focus_function(self.onFocus)
|
||||
|
||||
def show_menu(self, ev, pos=0, *args, **kwargs):
|
||||
if self.tab.list.get_count() == 0: return
|
||||
menu = self.get_menu()
|
||||
if pos != 0:
|
||||
self.tab.PopupMenu(menu, pos)
|
||||
else:
|
||||
self.tab.PopupMenu(menu, ev.GetPosition())
|
||||
|
||||
def show_menu_by_key(self, ev):
|
||||
if self.tab.list.get_count() == 0:
|
||||
return
|
||||
if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU:
|
||||
self.show_menu(widgetUtils.MENU, pos=self.tab.list.list.GetPosition())
|
||||
|
||||
def get_menu(self):
|
||||
m = menus.postMenu()
|
||||
p = self.get_post()
|
||||
if p.has_key("likes") == False:
|
||||
m.like.Enable(False)
|
||||
elif p["likes"]["user_likes"] == 1:
|
||||
m.like.Enable(False)
|
||||
m.dislike.Enable(True)
|
||||
if p.has_key("comments") == False:
|
||||
m.comment.Enable(False)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_post, menuitem=m.open)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.do_like, menuitem=m.like)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.do_dislike, menuitem=m.dislike)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.do_comment, menuitem=m.comment)
|
||||
return m
|
||||
|
||||
def do_like(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
user = post[self.user_key]
|
||||
id = post[self.post_key]
|
||||
if post.has_key("type"):
|
||||
type_ = post["type"]
|
||||
else:
|
||||
type_ = "post"
|
||||
l = self.session.vk.client.likes.add(owner_id=user, item_id=id, type=type_)
|
||||
self.session.db[self.name]["items"][self.tab.list.get_selected()]["likes"]["count"] = l["likes"]
|
||||
self.session.db[self.name]["items"][self.tab.list.get_selected()]["likes"]["user_likes"] = 1
|
||||
# Translators: This will be used when user presses like.
|
||||
output.speak(_(u"You liked this"))
|
||||
|
||||
def do_dislike(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
user = post[self.user_key]
|
||||
id = post[self.post_key]
|
||||
if post.has_key("type"):
|
||||
type_ = post["type"]
|
||||
else:
|
||||
type_ = "post"
|
||||
l = self.session.vk.client.likes.delete(owner_id=user, item_id=id, type=type_)
|
||||
self.session.db[self.name]["items"][self.tab.list.get_selected()]["likes"]["count"] = l["likes"]
|
||||
self.session.db[self.name]["items"][self.tab.list.get_selected()]["likes"]["user_likes"] = 2
|
||||
# Translators: This will be user in 'dislike'
|
||||
output.speak(_(u"You don't like this"))
|
||||
|
||||
def do_comment(self, *args, **kwargs):
|
||||
comment = messages.comment(title=_(u"Add a comment"), caption="", text="")
|
||||
if comment.message.get_response() == widgetUtils.OK:
|
||||
msg = comment.message.get_text().encode("utf-8")
|
||||
post = self.get_post()
|
||||
try:
|
||||
user = post[self.user_key]
|
||||
id = post[self.post_key]
|
||||
self.session.vk.client.wall.addComment(owner_id=user, post_id=id, text=msg)
|
||||
output.speak(_(u"You've posted a comment"))
|
||||
except Exception as msg:
|
||||
print msg
|
||||
|
||||
def get_event(self, ev):
|
||||
if ev.GetKeyCode() == wx.WXK_RETURN and ev.ControlDown() and ev.ShiftDown(): event = "pause_audio"
|
||||
@@ -138,7 +223,7 @@ class baseBuffer(object):
|
||||
if post.has_key("type") and post["type"] == "audio":
|
||||
pub.sendMessage("play-audio", audio_object=post["audio"]["items"][0])
|
||||
|
||||
def open_post(self):
|
||||
def open_post(self, *args, **kwargs):
|
||||
post = self.session.db[self.name]["items"][self.tab.list.get_selected()]
|
||||
if post.has_key("type") and post["type"] == "audio":
|
||||
a = posts.audio(self.session, post["audio"]["items"])
|
||||
@@ -161,9 +246,19 @@ class baseBuffer(object):
|
||||
else:
|
||||
return [post["source_id"]]
|
||||
|
||||
def onFocus(self, *args,**kwargs):
|
||||
""" Function executed when the item in a list is selected.
|
||||
For this buffer it updates the date of posts in the list."""
|
||||
post = self.session.db[self.name]["items"][self.tab.list.get_selected()]
|
||||
original_date = arrow.get(post["date"])
|
||||
created_at = original_date.humanize(locale=languageHandler.getLanguage())
|
||||
self.tab.list.list.SetStringItem(self.tab.list.get_selected(), 2, created_at)
|
||||
|
||||
|
||||
class feedBuffer(baseBuffer):
|
||||
|
||||
def get_items(self, show_nextpage=False):
|
||||
if self.can_get_items == False: return
|
||||
retrieved = True
|
||||
try:
|
||||
num = getattr(self.session, "get_page")(show_nextpage=show_nextpage, name=self.name, *self.args, **self.kwargs)
|
||||
@@ -197,6 +292,11 @@ class feedBuffer(baseBuffer):
|
||||
else:
|
||||
return False
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(feedBuffer, self).__init__(*args, **kwargs)
|
||||
self.user_key = "from_id"
|
||||
self.post_key = "id"
|
||||
|
||||
class audioBuffer(feedBuffer):
|
||||
def create_tab(self, parent):
|
||||
self.tab = home.audioTab(parent)
|
||||
@@ -210,7 +310,7 @@ class audioBuffer(feedBuffer):
|
||||
selected = self.tab.list.get_selected()
|
||||
pub.sendMessage("play-audio", audio_object=self.session.db[self.name]["items"][selected])
|
||||
|
||||
def open_post(self):
|
||||
def open_post(self, *args, **kwargs):
|
||||
selected = self.tab.list.get_selected()
|
||||
audios = [self.session.db[self.name]["items"][selected]]
|
||||
a = posts.audio(self.session, audios)
|
||||
@@ -240,8 +340,75 @@ class audioBuffer(feedBuffer):
|
||||
return False
|
||||
|
||||
def get_more_items(self, *args, **kwargs):
|
||||
# Translators: Some buffers can't use the get previous item feature due to API limitations.
|
||||
output.speak(_(u"This buffer doesn't support getting more items."))
|
||||
|
||||
def onFocus(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def add_to_library(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
args = {}
|
||||
args["audio_id"] = post["id"]
|
||||
if post.has_key("album_id"):
|
||||
args["album_id"] = post["album_id"]
|
||||
args["owner_id"] = post["owner_id"]
|
||||
audio = self.session.vk.client.audio.add(**args)
|
||||
if audio != None and int(audio) > 21:
|
||||
output.speak(_(u"Audio added to your library"))
|
||||
|
||||
def remove_from_library(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
args = {}
|
||||
args["audio_id"] = post["id"]
|
||||
args["owner_id"] = self.session.user_id
|
||||
result = self.session.vk.client.audio.delete(**args)
|
||||
if int(result) == 1:
|
||||
output.speak(_(u"Removed audio from library"))
|
||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||
|
||||
def move_to_album(self, *args, **kwargs):
|
||||
album = selector.audioAlbum(_(u"Select the album where you want to move this song"), self.session)
|
||||
if album.item == None: return
|
||||
id = self.get_post()["id"]
|
||||
response = self.session.vk.client.audio.moveToAlbum(album_id=album.item, audio_ids=id)
|
||||
if response == 1:
|
||||
# Translators: Used when the user has moved an audio to an album.
|
||||
output.speak(_(u"Moved"))
|
||||
|
||||
def get_menu(self):
|
||||
p = self.get_post()
|
||||
m = menus.audioMenu()
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_post, menuitem=m.open)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.play_audio, menuitem=m.play)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.move_to_album, menuitem=m.move)
|
||||
# if owner_id is the current user, the audio is added to the user's audios.
|
||||
if p["owner_id"] == self.session.user_id:
|
||||
m.library.SetItemLabel(_(u"&Remove from library"))
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.remove_from_library, menuitem=m.library)
|
||||
else:
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.add_to_library, menuitem=m.library)
|
||||
return m
|
||||
|
||||
class audioAlbum(audioBuffer):
|
||||
|
||||
def create_tab(self, parent):
|
||||
self.tab = home.audioAlbumTab(parent)
|
||||
self.tab.play.Enable(False)
|
||||
self.tab.play_all.Enable(False)
|
||||
|
||||
def connect_events(self):
|
||||
super(audioAlbum, self).connect_events()
|
||||
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_album)
|
||||
|
||||
def load_album(self, *args, **kwargs):
|
||||
output.speak(_(u"Loading album..."))
|
||||
self.can_get_items = True
|
||||
self.tab.load.Enable(False)
|
||||
wx.CallAfter(self.get_items)
|
||||
self.tab.play.Enable(True)
|
||||
self.tab.play_all.Enable(True)
|
||||
|
||||
class empty(object):
|
||||
|
||||
def __init__(self, name=None, parent=None, *args, **kwargs):
|
||||
@@ -258,13 +425,21 @@ class empty(object):
|
||||
|
||||
class chatBuffer(baseBuffer):
|
||||
|
||||
def onFocus(self, *args, **kwargs):
|
||||
msg = self.session.db[self.name]["items"][-1]
|
||||
if msg.has_key("read_state") and msg["read_state"] == 0 and msg["id"] not in self.reads:
|
||||
self.reads.append(msg["id"])
|
||||
self.session.db[self.name]["items"][-1]["read_state"] = 1
|
||||
|
||||
def create_tab(self, parent):
|
||||
self.tab = home.chatTab(parent)
|
||||
|
||||
def connect_events(self):
|
||||
widgetUtils.connect_event(self.tab.send, widgetUtils.BUTTON_PRESSED, self.send_chat_to_user)
|
||||
self.tab.set_focus_function(self.onFocus)
|
||||
|
||||
def get_items(self, show_nextpage=False):
|
||||
if self.can_get_items == False: return
|
||||
retrieved = True # Control variable for handling unauthorised/connection errors.
|
||||
try:
|
||||
num = getattr(self.session, "get_messages")(name=self.name, *self.args, **self.kwargs)
|
||||
@@ -290,6 +465,10 @@ class chatBuffer(baseBuffer):
|
||||
if text == "": return
|
||||
response = self.session.vk.client.messages.send(user_id=self.kwargs["user_id"], message=text)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(chatBuffer, self).__init__(*args, **kwargs)
|
||||
self.reads = []
|
||||
|
||||
class peopleBuffer(feedBuffer):
|
||||
|
||||
def create_tab(self, parent):
|
||||
@@ -302,3 +481,26 @@ class peopleBuffer(feedBuffer):
|
||||
def new_chat(self, *args, **kwargs):
|
||||
user_id = self.session.db[self.name]["items"][self.tab.list.get_selected()]["id"]
|
||||
pub.sendMessage("new-chat", user_id=user_id)
|
||||
|
||||
def onFocus(self, *args, **kwargs):
|
||||
post = self.session.db[self.name]["items"][self.tab.list.get_selected()]
|
||||
if post.has_key("last_seen") == False: return
|
||||
original_date = arrow.get(post["last_seen"]["time"])
|
||||
created_at = original_date.humanize(locale=languageHandler.getLanguage())
|
||||
self.tab.list.list.SetStringItem(self.tab.list.get_selected(), 1, created_at)
|
||||
|
||||
def open_timeline(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def get_menu(self, *args, **kwargs):
|
||||
m = menus.peopleMenu()
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.new_chat, menuitem=m.message)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_timeline, menuitem=m.timeline)
|
||||
return m
|
||||
|
||||
def open_post(self, *args, **kwargs): pass
|
||||
|
||||
def play_audio(self, *args, **kwargs): pass
|
||||
|
||||
def pause_audio(self, *args, **kwargs): pass
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import time
|
||||
import os
|
||||
import wx
|
||||
import utils
|
||||
@@ -11,13 +12,16 @@ import posts
|
||||
import webbrowser
|
||||
import logging
|
||||
import longpoolthread
|
||||
import selector
|
||||
from vk.exceptions import VkAuthError
|
||||
from pubsub import pub
|
||||
from mysc.repeating_timer import RepeatingTimer
|
||||
from mysc.thread_utils import call_threaded
|
||||
from mysc import localization
|
||||
from sessionmanager import session
|
||||
from wxUI import (mainWindow, commonMessages)
|
||||
from wxUI.dialogs import search as searchDialogs
|
||||
from wxUI.dialogs import timeline
|
||||
from wxUI.dialogs import timeline, creation
|
||||
from update import updater
|
||||
|
||||
log = logging.getLogger("controller.main")
|
||||
@@ -55,18 +59,27 @@ class Controller(object):
|
||||
log.debug("Creating controls for the window...")
|
||||
posts_ = buffers.empty(parent=self.window.tb, name="posts")
|
||||
self.buffers.append(posts_)
|
||||
# Translators: Name for the posts tab in the tree view.
|
||||
self.window.add_buffer(posts_.tab, _(u"Posts"))
|
||||
home = buffers.baseBuffer(parent=self.window.tb, name="home_timeline", session=self.session, composefunc="compose_new", endpoint="newsfeed", count=self.session.settings["buffers"]["count_for_wall_buffers"])
|
||||
self.buffers.append(home)
|
||||
# Translators: Newsfeed's name in the tree view.
|
||||
self.window.insert_buffer(home.tab, _(u"Home"), self.window.search("posts"))
|
||||
self.repeatedUpdate = RepeatingTimer(180, self.update_all_buffers)
|
||||
self.repeatedUpdate.start()
|
||||
|
||||
self.readMarker = RepeatingTimer(120, self.mark_as_read)
|
||||
self.readMarker.start()
|
||||
|
||||
feed = buffers.feedBuffer(parent=self.window.tb, name="me_feed", composefunc="compose_status", session=self.session, endpoint="get", parent_endpoint="wall", extended=1, count=self.session.settings["buffers"]["count_for_wall_buffers"])
|
||||
self.buffers.append(feed)
|
||||
# Translators: Own user's wall name in the tree view.
|
||||
self.window.insert_buffer(feed.tab, _(u"My wall"), self.window.search("posts"))
|
||||
audios = buffers.empty(parent=self.window.tb, name="audios")
|
||||
self.buffers.append(audios)
|
||||
# Translators: name for the music category in the tree view.
|
||||
self.window.add_buffer(audios.tab, _(u"Music"))
|
||||
|
||||
audio = buffers.audioBuffer(parent=self.window.tb, name="me_audio", composefunc="compose_audio", session=self.session, endpoint="get", parent_endpoint="audio", full_list=True, count=self.session.settings["buffers"]["count_for_audio_buffers"])
|
||||
self.buffers.append(audio)
|
||||
self.window.insert_buffer(audio.tab, _(u"My audios"), self.window.search("audios"))
|
||||
@@ -76,6 +89,9 @@ class Controller(object):
|
||||
r_audio = buffers.audioBuffer(parent=self.window.tb, name="recommended_audio", composefunc="compose_audio", session=self.session, endpoint="getRecommendations", parent_endpoint="audio", full_list=True, count=self.session.settings["buffers"]["count_for_audio_buffers"])
|
||||
self.buffers.append(r_audio)
|
||||
self.window.insert_buffer(r_audio.tab, _(u"Recommendations"), self.window.search("audios"))
|
||||
albums = buffers.empty(parent=self.window.tb, name="albums")
|
||||
self.buffers.append(albums)
|
||||
self.window.insert_buffer(albums.tab, _(u"Albums"), self.window.search("audios"))
|
||||
people = buffers.empty(parent=self.window.tb, name="people")
|
||||
self.buffers.append(people)
|
||||
self.window.add_buffer(people.tab, _(u"People"))
|
||||
@@ -88,6 +104,7 @@ class Controller(object):
|
||||
timelines = buffers.empty(parent=self.window.tb, name="timelines")
|
||||
self.buffers.append(timelines)
|
||||
self.window.add_buffer(timelines.tab, _(u"Timelines"))
|
||||
self.window.realize()
|
||||
|
||||
def connect_events(self):
|
||||
log.debug("Connecting events to responses...")
|
||||
@@ -98,6 +115,7 @@ class Controller(object):
|
||||
pub.subscribe(self.view_post, "open-post")
|
||||
pub.subscribe(self.update_status_bar, "update-status-bar")
|
||||
pub.subscribe(self.chat_from_id, "new-chat")
|
||||
pub.subscribe(self.authorisation_failed, "authorisation-failed")
|
||||
widgetUtils.connect_event(self.window, widgetUtils.CLOSE_EVENT, self.exit)
|
||||
widgetUtils.connect_event(self.window, widgetUtils.MENU, self.update_buffer, menuitem=self.window.update_buffer)
|
||||
widgetUtils.connect_event(self.window, widgetUtils.MENU, self.check_for_updates, menuitem=self.window.check_for_updates)
|
||||
@@ -108,6 +126,9 @@ class Controller(object):
|
||||
widgetUtils.connect_event(self.window, widgetUtils.MENU, self.changelog, menuitem=self.window.changelog)
|
||||
widgetUtils.connect_event(self.window, widgetUtils.MENU, self.configuration, menuitem=self.window.settings_dialog)
|
||||
widgetUtils.connect_event(self.window, widgetUtils.MENU, self.new_timeline, menuitem=self.window.timeline)
|
||||
widgetUtils.connect_event(self.window, widgetUtils.MENU, self.create_audio_album, menuitem=self.window.audio_album)
|
||||
widgetUtils.connect_event(self.window, widgetUtils.MENU, self.delete_audio_album, menuitem=self.window.delete_audio_album)
|
||||
widgetUtils.connect_event(self.window, widgetUtils.MENU, self.check_documentation, menuitem=self.window.documentation)
|
||||
pub.subscribe(self.get_chat, "order-sent-message")
|
||||
|
||||
def disconnect_events(self):
|
||||
@@ -115,21 +136,31 @@ class Controller(object):
|
||||
pub.unsubscribe(self.in_post, "posted")
|
||||
pub.unsubscribe(self.download, "download-file")
|
||||
pub.unsubscribe(self.play_audio, "play-audio")
|
||||
pub.unsubscribe(self.authorisation_failed, "authorisation-failed")
|
||||
pub.unsubscribe(self.play_audios, "play-audios")
|
||||
pub.unsubscribe(self.view_post, "open-post")
|
||||
pub.unsubscribe(self.update_status_bar, "update-status-bar")
|
||||
|
||||
def authorisation_failed(self):
|
||||
commonMessages.bad_authorisation()
|
||||
|
||||
def login(self):
|
||||
self.window.change_status(_(u"Logging in VK"))
|
||||
self.session.login()
|
||||
self.window.change_status(_(u"Ready"))
|
||||
for i in self.buffers:
|
||||
if hasattr(i, "get_items"):
|
||||
# Translators: {0} will be replaced with the name of a buffer.
|
||||
self.window.change_status(_(u"Loading items for {0}").format(i.name,))
|
||||
i.get_items()
|
||||
self.window.change_status(_(u"Ready"))
|
||||
self.longpool = longpoolthread.worker(self.session)
|
||||
self.longpool.start()
|
||||
self.status_setter = RepeatingTimer(900, self.set_online)
|
||||
self.status_setter.start()
|
||||
self.set_online()
|
||||
self.create_unread_messages()
|
||||
wx.CallAfter(self.get_audio_albums, self.session.user_id)
|
||||
|
||||
def in_post(self, buffer):
|
||||
buffer = self.search(buffer)
|
||||
@@ -139,6 +170,7 @@ class Controller(object):
|
||||
|
||||
def update_all_buffers(self):
|
||||
log.debug("Updating buffers...")
|
||||
self.session.audio_albums = self.session.vk.client.audio.getAlbums(owner_id=self.session.user_id)["items"]
|
||||
for i in self.buffers:
|
||||
if hasattr(i, "get_items"):
|
||||
i.get_items()
|
||||
@@ -155,7 +187,6 @@ class Controller(object):
|
||||
player.player.play_all(audios)
|
||||
|
||||
def view_post(self, post_object, controller_):
|
||||
# print post_object
|
||||
p = getattr(posts, controller_)(self.session, post_object)
|
||||
p.dialog.get_response()
|
||||
p.dialog.Destroy()
|
||||
@@ -191,6 +222,7 @@ class Controller(object):
|
||||
newbuff = buffers.audioBuffer(parent=self.window.tb, name=u"{0}_audiosearch".format(q.decode("utf-8"),), session=self.session, composefunc="compose_audio", parent_endpoint="audio", endpoint="search", q=q, count=count, auto_complete=auto_complete, lyrics=lyrics, performer_only=performer_only, sort=sort)
|
||||
self.buffers.append(newbuff)
|
||||
call_threaded(newbuff.get_items)
|
||||
# Translators: {0} will be replaced with the search term.
|
||||
self.window.insert_buffer(newbuff.tab, _(u"Search for {0}").format(q.decode("utf-8"),), self.window.search("audios"))
|
||||
|
||||
def update_status_bar(self, status):
|
||||
@@ -221,12 +253,9 @@ class Controller(object):
|
||||
b = self.get_current_buffer()
|
||||
if not hasattr(b, "get_users"):
|
||||
b = self.search("home_timeline")
|
||||
# ids = b.get_users()
|
||||
d = []
|
||||
# for i in ids:
|
||||
# d.append((i, self.session.get_user_name(i)))
|
||||
for i in self.session.db["users"]:
|
||||
d.append((i, self.session.get_user_name(i)))
|
||||
d.append((i, self.session.get_user_name(i, "nom")))
|
||||
for i in self.session.db["groups"]:
|
||||
d.append((-i, self.session.get_user_name(-i)))
|
||||
a = timeline.timelineDialog([i[1] for i in d])
|
||||
@@ -240,12 +269,19 @@ class Controller(object):
|
||||
if user_id == None:
|
||||
commonMessages.no_user_exist()
|
||||
return
|
||||
print user_id
|
||||
if buffertype == "audio":
|
||||
buffer = buffers.audioBuffer(parent=self.window.tb, name="{0}_audio".format(user_id,), composefunc="compose_audio", session=self.session, endpoint="get", parent_endpoint="audio", full_list=True, count=self.session.settings["buffers"]["count_for_audio_buffers"], user_id=user_id)
|
||||
name_ = _(u"{0}'s audios").format(user,)
|
||||
buffer = buffers.audioBuffer(parent=self.window.tb, name="{0}_audio".format(user_id,), composefunc="compose_audio", session=self.session, endpoint="get", parent_endpoint="audio", full_list=True, count=self.session.settings["buffers"]["count_for_audio_buffers"], owner_id=user_id)
|
||||
# Translators: {0} will be replaced with an user.
|
||||
name_ = _(u"{0}'s audios").format(self.session.get_user_name(user_id, "gen"),)
|
||||
elif buffertype == "wall":
|
||||
buffer = buffers.feedBuffer(parent=self.window.tb, name="{0}_feed".format(user_id,), composefunc="compose_status", session=self.session, endpoint="get", parent_endpoint="wall", extended=1, count=self.session.settings["buffers"]["count_for_wall_buffers"], owner_id=user_id)
|
||||
name_ = _(u"{0}'s wall posts").format(user,)
|
||||
# Translators: {0} will be replaced with an user.
|
||||
name_ = _(u"{0}'s wall posts").format(self.session.get_user_name(user_id, "gen"),)
|
||||
elif buffertype == "friends":
|
||||
buffer = buffers.peopleBuffer(parent=self.window.tb, name="friends_{0}".format(user_id,), composefunc="compose_person", session=self.session, endpoint="get", parent_endpoint="friends", count=5000, fields="uid, first_name, last_name, last_seen", user_id=user_id)
|
||||
# Translators: {0} will be replaced with an user.
|
||||
name_ = _(u"{0}'s friends").format(self.session.get_user_name(user_id, "friends"),)
|
||||
self.buffers.append(buffer)
|
||||
call_threaded(self.complete_buffer_creation, buffer=buffer, name_=name_, position=self.window.search("timelines"))
|
||||
|
||||
@@ -264,19 +300,23 @@ class Controller(object):
|
||||
if i.kwargs.has_key("user_id") and i.kwargs["user_id"] == user_id: return i
|
||||
return None
|
||||
|
||||
def chat_from_id(self, user_id):
|
||||
def chat_from_id(self, user_id, setfocus=True):
|
||||
b = self.search_chat_buffer(user_id)
|
||||
if b != None:
|
||||
pos = self.window.search(b.name)
|
||||
if setfocus:
|
||||
self.window.change_buffer(pos)
|
||||
return b.tab.text.SetFocus()
|
||||
return
|
||||
buffer = buffers.chatBuffer(parent=self.window.tb, name="{0}_messages".format(user_id,), composefunc="compose_message", session=self.session, count=200, user_id=user_id, rev=1)
|
||||
self.buffers.append(buffer)
|
||||
self.window.insert_buffer(buffer.tab, _(u"Chat with {0}").format(self.session.get_user_name(user_id,)), self.window.search("chats"))
|
||||
# Translators: {0} will be replaced with an user.
|
||||
self.window.insert_buffer(buffer.tab, _(u"Chat with {0}").format(self.session.get_user_name(user_id, "ins")), self.window.search("chats"))
|
||||
if setfocus:
|
||||
pos = self.window.search(buffer.name)
|
||||
self.window.change_buffer(pos)
|
||||
wx.CallAfter(buffer.get_items)
|
||||
buffer.tab.text.SetFocus()
|
||||
if setfocus: buffer.tab.text.SetFocus()
|
||||
return True
|
||||
|
||||
def get_chat(self, obj=None):
|
||||
@@ -302,3 +342,72 @@ class Controller(object):
|
||||
num = self.session.order_buffer(buffer.name, data, True)
|
||||
buffer.insert(self.session.db[buffer.name]["items"][-1], False)
|
||||
self.session.soundplayer.play("chat.ogg")
|
||||
|
||||
def set_online(self):
|
||||
try:
|
||||
r = self.session.vk.client.account.setOnline()
|
||||
except:
|
||||
log.error("Error in setting online for the current user")
|
||||
|
||||
def create_unread_messages(self):
|
||||
msgs = self.session.vk.client.messages.getDialogs(count=200, unread=1)
|
||||
for i in msgs["items"]:
|
||||
wx.CallAfter(self.chat_from_id, i["message"]["user_id"], setfocus=False)
|
||||
|
||||
def mark_as_read(self):
|
||||
ids = ""
|
||||
for i in self.buffers:
|
||||
if hasattr(i, "reads"):
|
||||
for z in i.reads:
|
||||
ids = ids+"%d," % (z,)
|
||||
i.reads = []
|
||||
if ids != "":
|
||||
response = self.session.vk.client.messages.markAsRead(message_ids=ids)
|
||||
|
||||
def get_audio_albums(self, user_id=None):
|
||||
albums = self.session.vk.client.audio.getAlbums(owner_id=user_id)
|
||||
self.session.audio_albums = albums["items"]
|
||||
for i in albums["items"]:
|
||||
buffer = buffers.audioAlbum(parent=self.window.tb, name="{0}_audio_album".format(i["id"],), composefunc="compose_audio", session=self.session, endpoint="get", parent_endpoint="audio", full_list=True, count=self.session.settings["buffers"]["count_for_audio_buffers"], user_id=user_id, album_id=i["id"])
|
||||
buffer.can_get_items = False
|
||||
# Translators: {0} Will be replaced with an audio album's title.
|
||||
name_ = _(u"Album: {0}").format(i["title"],)
|
||||
self.buffers.append(buffer)
|
||||
self.window.insert_buffer(buffer.tab, name_, self.window.search("albums"))
|
||||
buffer.get_items()
|
||||
# inserts a pause of 1 second here, so we'll avoid errors 6 in VK.
|
||||
|
||||
def create_audio_album(self, *args, **kwargs):
|
||||
d = creation.audio_album()
|
||||
if d.get_response() == widgetUtils.OK and d.get("title") != "":
|
||||
response = self.session.vk.client.audio.addAlbum(title=d.get("title"))
|
||||
if response.has_key("album_id") == False: return
|
||||
album_id = response["album_id"]
|
||||
buffer = buffers.audioAlbum(parent=self.window.tb, name="{0}_audio_album".format(album_id,), composefunc="compose_audio", session=self.session, endpoint="get", parent_endpoint="audio", full_list=True, count=self.session.settings["buffers"]["count_for_audio_buffers"], user_id=self.session.user_id, album_id=album_id)
|
||||
buffer.can_get_items = False
|
||||
# Translators: {0} will be replaced with an audio album's title.
|
||||
name_ = _(u"Album: {0}").format(d.get("title"),)
|
||||
self.buffers.append(buffer)
|
||||
self.window.insert_buffer(buffer.tab, name_, self.window.search("albums"))
|
||||
buffer.get_items()
|
||||
self.session.audio_albums = self.session.vk.client.audio.getAlbums(owner_id=self.session.user_id)["items"]
|
||||
|
||||
def delete_audio_album(self, *args, **kwargs):
|
||||
answer = selector.audioAlbum(_(u"Select the album you want to delete"), self.session)
|
||||
if answer.item == None:
|
||||
return
|
||||
response = commonMessages.delete_audio_album()
|
||||
if response != widgetUtils.YES: return
|
||||
removal = self.session.vk.client.audio.deleteAlbum(album_id=answer.item)
|
||||
buffer = self.search("{0}_audio_album".format(answer.item,))
|
||||
buff = self.window.search(buffer.name)
|
||||
self.window.remove_buffer(buff)
|
||||
self.buffers.remove(buffer)
|
||||
del buffer
|
||||
self.session.audio_albums = self.session.vk.client.audio.getAlbums(owner_id=self.session.user_id)["items"]
|
||||
|
||||
def check_documentation(self, *args, **kwargs):
|
||||
lang = localization.get("documentation")
|
||||
os.chdir("documentation/%s" % (lang,))
|
||||
webbrowser.open("manual.html")
|
||||
os.chdir("../../")
|
||||
|
@@ -34,6 +34,7 @@ class audioPlayer(object):
|
||||
if self.is_working == False:
|
||||
self.is_working = True
|
||||
self.stream = URLStream(url=url["url"])
|
||||
# Translators: {0} will be replaced with a song's title and {1} with the artist.
|
||||
msg = _(u"Playing {0} by {1}").format(url["title"], url["artist"])
|
||||
pub.sendMessage("update-status-bar", status=msg)
|
||||
self.stream.volume = self.vol/100.0
|
||||
@@ -80,7 +81,7 @@ class audioPlayer(object):
|
||||
self.worker.start()
|
||||
|
||||
def player_function(self):
|
||||
if self.stream != None and self.stream.is_playing == False and self.stopped == False:
|
||||
if self.stream != None and self.stream.is_playing == False and self.stopped == False and len(self.stream) == self.stream.position:
|
||||
if len(self.queue) == 0:
|
||||
self.worker.cancel()
|
||||
return
|
||||
|
@@ -23,6 +23,7 @@ def get_user(id, profiles):
|
||||
for i in profiles:
|
||||
if i["id"] == id:
|
||||
return u"{0} {1}".format(i["first_name"], i["last_name"])
|
||||
# Translators: This string is user when socializer can't find the right user information.
|
||||
return _(u"Unknown username")
|
||||
|
||||
def add_attachment(attachment):
|
||||
@@ -89,6 +90,9 @@ class postController(object):
|
||||
comments_ = []
|
||||
for i in self.comments["items"]:
|
||||
from_ = get_user(i["from_id"], self.comments["profiles"])
|
||||
if i.has_key("reply_to_user"):
|
||||
extra_info = get_user(i["reply_to_user"], self.comments["profiles"])
|
||||
from_ = _(u"{0} Has replied to {1}").format(from_, extra_info)
|
||||
if len(i["text"]) > 140:
|
||||
text = i["text"][:141]
|
||||
else:
|
||||
@@ -102,9 +106,11 @@ class postController(object):
|
||||
def get_post_information(self):
|
||||
from_ = self.session.get_user_name(self.post[self.user_identifier])
|
||||
if self.post.has_key("copy_history"):
|
||||
# Translators: {0} will be replaced with an user.
|
||||
title = _(u"repost from {0}").format(from_,)
|
||||
else:
|
||||
if self.post.has_key("from_id") and self.post.has_key("owner_id"):
|
||||
# Translators: {0} will be replaced with the user who is posting, and {2} with the wall owner.
|
||||
title = _(u"Post from {0} in the {1}'s wall").format(self.session.get_user_name(self.post["from_id"]), self.session.get_user_name(self.post["owner_id"]))
|
||||
else:
|
||||
title = _(u"Post from {0}").format(from_,)
|
||||
@@ -151,7 +157,7 @@ class postController(object):
|
||||
self.get_reposts()
|
||||
self.get_comments()
|
||||
if self.post["comments"]["can_post"] == 0:
|
||||
self.dialog.disable("add_comment")
|
||||
self.dialog.disable("comment")
|
||||
if self.post["likes"]["can_like"] == 0 and self.post["likes"]["user_likes"] == 0:
|
||||
self.dialog.disable("like")
|
||||
elif self.post["likes"]["user_likes"] == 1:
|
||||
|
23
src/controller/selector.py
Normal file
23
src/controller/selector.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import widgetUtils
|
||||
from wxUI.dialogs import selector as gui
|
||||
|
||||
class audioAlbum(object):
|
||||
|
||||
def __init__(self, title, session):
|
||||
super(audioAlbum, self).__init__()
|
||||
self.item = None
|
||||
self.session = session
|
||||
self.dialog = gui.selectAlbum(title=title, albums=self.get_albums_as_string())
|
||||
response = self.dialog.get_response()
|
||||
if response == widgetUtils.OK:
|
||||
self.item = self.search_item(self.dialog.get_string())
|
||||
|
||||
def get_albums_as_string(self):
|
||||
return [i["title"] for i in self.session.audio_albums]
|
||||
|
||||
def search_item(self, item):
|
||||
for i in self.session.audio_albums:
|
||||
if i["title"] == item:
|
||||
return i["id"]
|
||||
return None
|
@@ -1,6 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
import fix_requests
|
||||
import fix_win32com
|
||||
|
||||
def setup():
|
||||
fix_requests.fix()
|
||||
|
||||
if hasattr(sys, "frozen"):
|
||||
fix_win32com.fix()
|
||||
|
5
src/fixes/fix_win32com.py
Normal file
5
src/fixes/fix_win32com.py
Normal file
@@ -0,0 +1,5 @@
|
||||
import win32com.client
|
||||
def fix():
|
||||
if win32com.client.gencache.is_readonly == True:
|
||||
win32com.client.gencache.is_readonly = False
|
||||
win32com.client.gencache.Rebuild()
|
@@ -1,7 +1,7 @@
|
||||
from pywintypes import com_error
|
||||
import win32com
|
||||
import paths
|
||||
win32com.__gen_path__=paths.data_path(u"com_cache")
|
||||
win32com.__gen_path__=paths.com_path()
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.join(win32com.__gen_path__, "."))
|
||||
@@ -32,3 +32,9 @@ def load_com(*names):
|
||||
raise com_error("Unable to load any of the provided com objects.")
|
||||
return result
|
||||
|
||||
|
||||
def preexec():
|
||||
global fixed
|
||||
if fixed==False:
|
||||
gencache._GetModule=patched_getmodule
|
||||
fixed=True
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import logger
|
||||
import sys
|
||||
import fixes
|
||||
if hasattr(sys, "frozen"):
|
||||
@@ -9,7 +10,6 @@ import widgetUtils
|
||||
import paths
|
||||
import config
|
||||
import output
|
||||
import logger
|
||||
import logging
|
||||
import keys
|
||||
import application
|
||||
|
@@ -1,28 +1,37 @@
|
||||
# *- coding: utf-8 -*-
|
||||
import logging as original_logging
|
||||
logging = original_logging.getLogger('core.output')
|
||||
logger = original_logging.getLogger('core.output')
|
||||
|
||||
from accessible_output2 import outputs
|
||||
import sys
|
||||
|
||||
speaker = None
|
||||
retries = 0
|
||||
|
||||
def speak(text, interrupt=0):
|
||||
global speaker
|
||||
global speaker, retries
|
||||
if not speaker:
|
||||
setup()
|
||||
try:
|
||||
speaker.speak(text, interrupt)
|
||||
speaker.braille(text)
|
||||
except:
|
||||
if retries < 5:
|
||||
retries = retries + 1
|
||||
speak(text)
|
||||
# speaker.braille(text)
|
||||
|
||||
def setup ():
|
||||
global speaker
|
||||
logging.debug("Initializing output subsystem.")
|
||||
logger.debug("Initializing output subsystem.")
|
||||
try:
|
||||
# speaker = speech.Speaker(speech.outputs.Sapi5())
|
||||
# else:
|
||||
speaker = outputs.auto.Auto()
|
||||
except:
|
||||
return logging.exception("Output: Error during initialization.")
|
||||
logger.exception("Output: Error during initialization.")
|
||||
|
||||
def enable_sapi():
|
||||
speaker = outputs.sapi.SAPI5()
|
||||
|
||||
def copy(text):
|
||||
import win32clipboard
|
||||
|
21
src/paths.py
21
src/paths.py
@@ -2,7 +2,7 @@
|
||||
import platform
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
#import logging
|
||||
from platform_utils import paths as paths_
|
||||
|
||||
from functools import wraps
|
||||
@@ -10,7 +10,7 @@ from functools import wraps
|
||||
mode = "portable"
|
||||
directory = None
|
||||
|
||||
log = logging.getLogger("paths")
|
||||
#log = logging.getLogger("paths")
|
||||
|
||||
def merge_paths(func):
|
||||
@wraps(func)
|
||||
@@ -31,7 +31,7 @@ def config_path():
|
||||
elif mode == "installed":
|
||||
path = data_path("config")
|
||||
if not os.path.exists(path):
|
||||
log.debug("%s path does not exist, creating..." % (path,))
|
||||
# log.debug("%s path does not exist, creating..." % (path,))
|
||||
os.mkdir(path)
|
||||
return path
|
||||
|
||||
@@ -44,7 +44,7 @@ def logs_path():
|
||||
elif mode == "installed":
|
||||
path = data_path("logs")
|
||||
if not os.path.exists(path):
|
||||
log.debug("%s path does not exist, creating..." % (path,))
|
||||
# log.debug("%s path does not exist, creating..." % (path,))
|
||||
os.mkdir(path)
|
||||
return path
|
||||
|
||||
@@ -65,3 +65,16 @@ def locale_path():
|
||||
@merge_paths
|
||||
def sound_path():
|
||||
return app_path(u"sounds")
|
||||
|
||||
@merge_paths
|
||||
def com_path():
|
||||
global mode, directory
|
||||
if mode == "portable":
|
||||
if directory != None: path = os.path.join(directory, "com_cache")
|
||||
elif directory == None: path = app_path(u"com_cache")
|
||||
elif mode == "installed":
|
||||
path = data_path(u"com_cache")
|
||||
if not os.path.exists(path):
|
||||
# log.debug("%s path does not exist, creating..." % (path,))
|
||||
os.mkdir(path)
|
||||
return path
|
||||
|
@@ -8,6 +8,8 @@ import logging
|
||||
import utils
|
||||
import sound
|
||||
from config_utils import Configuration, ConfigurationResetException
|
||||
from pubsub import pub
|
||||
|
||||
log = logging.getLogger("session")
|
||||
|
||||
sessions = {}
|
||||
@@ -17,15 +19,6 @@ sessions = {}
|
||||
# I've added the Date identifier (this is a field in unix time format), for special objects (like friendship indicators) because these objects doesn't have an own identifier.
|
||||
identifiers = ["aid", "gid", "uid", "pid", "id", "post_id", "nid", "date"]
|
||||
|
||||
platforms = {1: _(u"Movile application"),
|
||||
2: _(u"iPhone"),
|
||||
3: _(u"iPad"),
|
||||
4: _(u"Android"),
|
||||
5: _(u"Windows phone"),
|
||||
6: _(u"Windows 8"),
|
||||
7: _(u"Web or desktop app")
|
||||
}
|
||||
|
||||
def find_item(list, item):
|
||||
""" Finds an item in a list by taking an identifier"""
|
||||
# determines the kind of identifier that we are using
|
||||
@@ -52,9 +45,9 @@ def add_attachment(attachment):
|
||||
elif attachment["type"] == "photo":
|
||||
msg = attachment["photo"]["text"]
|
||||
if msg == "":
|
||||
return "photo with no description available"
|
||||
return _(u"photo with no description available")
|
||||
elif attachment["type"] == "video":
|
||||
msg = u"video: {0}".format(attachment["video"]["title"],)
|
||||
msg = _(u"video: {0}").format(attachment["video"]["title"],)
|
||||
return msg
|
||||
|
||||
def add_text(status):
|
||||
@@ -71,14 +64,17 @@ def add_text(status):
|
||||
return message
|
||||
|
||||
def compose_person(status, session):
|
||||
global platforms
|
||||
if status.has_key("last_seen"):
|
||||
original_date = arrow.get(status["last_seen"]["time"])
|
||||
last_seen = _(u"{0} from {1}").format(original_date.humanize(locale=languageHandler.getLanguage()), platforms[status["last_seen"]["platform"]])
|
||||
# Translators: This is the date of last seen
|
||||
last_seen = _(u"{0}").format(original_date.humanize(locale=languageHandler.getLanguage()),)
|
||||
elif status.has_key("last_seen") == False and status.has_key("deactivated"):
|
||||
last_seen = _(u"Account deactivated")
|
||||
return [u"{0} {1}".format(status["first_name"], status["last_name"]), last_seen]
|
||||
|
||||
def compose_new(status, session):
|
||||
""" This method is used to compose an item of the news feed."""
|
||||
user = session.get_user_name(status["source_id"])
|
||||
user = session.get_user_name(status["source_id"], case_name="nom")
|
||||
if status.has_key("copy_history"):
|
||||
user = _(u"{0} has shared the {1}'s post").format(user, session.get_user_name(status["copy_history"][0]["owner_id"]))
|
||||
message = ""
|
||||
@@ -91,6 +87,8 @@ def compose_new(status, session):
|
||||
if message == "":
|
||||
message = "no description available"
|
||||
elif status["type"] == "audio":
|
||||
# removes deleted audios.
|
||||
status["audio"] = clean_audio(status["audio"])
|
||||
if status["audio"]["count"] == 1:
|
||||
message = _(u"{0} has added an audio: {1}").format(user, u", ".join(compose_audio(status["audio"]["items"][0], session)),)
|
||||
else:
|
||||
@@ -102,7 +100,7 @@ def compose_new(status, session):
|
||||
elif status["type"] == "friend":
|
||||
msg_users = u""
|
||||
for i in status["friends"]["items"]:
|
||||
msg_users = msg_users + u"{0}, ".format(session.get_user_name(i["user_id"]))
|
||||
msg_users = msg_users + u"{0}, ".format(session.get_user_name(i["user_id"], "nom"))
|
||||
message = _(u"{0} hadded friends: {1}").format(user, msg_users)
|
||||
elif status["type"] == "video":
|
||||
if status["video"]["count"] == 1:
|
||||
@@ -117,15 +115,22 @@ def compose_new(status, session):
|
||||
if status["type"] != "post": print status
|
||||
return [user, message, created_at]
|
||||
|
||||
def clean_audio(audio):
|
||||
for i in audio["items"][:]:
|
||||
if type(i) == bool:
|
||||
audio["items"].remove(i)
|
||||
audio["count"] = audio["count"] -1
|
||||
return audio
|
||||
|
||||
def compose_message(message, session):
|
||||
user = session.get_user_name(message["from_id"])
|
||||
user = session.get_user_name(message["from_id"], "nom")
|
||||
original_date = arrow.get(message["date"])
|
||||
created_at = original_date.format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.getLanguage())
|
||||
body = message["body"]
|
||||
return [u"{2}, {0} {1}".format(body, created_at, user)]
|
||||
|
||||
def compose_status(status, session):
|
||||
user = session.get_user_name(status["from_id"])
|
||||
user = session.get_user_name(status["from_id"], "nom")
|
||||
if status.has_key("copy_history"):
|
||||
user = _(u"{0} has shared the {1}'s post").format(user, session.get_user_name(status["copy_history"][0]["owner_id"]))
|
||||
message = ""
|
||||
@@ -220,9 +225,15 @@ class vkSession(object):
|
||||
self.get_my_data()
|
||||
|
||||
def authorise(self):
|
||||
try:
|
||||
self.vk.login(self.settings["vk"]["user"], self.settings["vk"]["password"])
|
||||
self.settings["vk"]["token"] = self.vk.client._session.access_token
|
||||
self.settings.write()
|
||||
except:
|
||||
self.settings["vk"]["user"] = ""
|
||||
self.settings["vk"]["password"] = ""
|
||||
self.settings.write()
|
||||
pub.sendMessage("authorisation-failed")
|
||||
|
||||
def post_wall_status(self, message, *args, **kwargs):
|
||||
""" Sends a post to an user, group or community wall."""
|
||||
@@ -258,9 +269,11 @@ class vkSession(object):
|
||||
if data != None:
|
||||
if type(data) == dict:
|
||||
num = self.order_buffer(name, data["items"], show_nextpage)
|
||||
if data["items"][0].has_key("first_name"):
|
||||
if len(data["items"]) > 0 and data["items"][0].has_key("first_name"):
|
||||
data2 = {"profiles": [], "groups": []}
|
||||
for i in data["items"]:
|
||||
self.db["users"][i["id"]] = u"{0} {1}".format(i["first_name"], i["last_name"])
|
||||
data2["profiles"].append(i)
|
||||
self.process_usernames(data2)
|
||||
if data.has_key("profiles") and data.has_key("groups"):
|
||||
self.process_usernames(data)
|
||||
else:
|
||||
@@ -273,15 +286,18 @@ class vkSession(object):
|
||||
num = self.order_buffer(name, data["items"], False)
|
||||
return num
|
||||
|
||||
def get_user_name(self, user_id):
|
||||
def get_user_name(self, user_id, case_name="gen"):
|
||||
if user_id > 0:
|
||||
if self.db["users"].has_key(user_id):
|
||||
return self.db["users"][user_id]
|
||||
if self.db["users"][user_id].has_key(case_name):
|
||||
return self.db["users"][user_id][case_name]
|
||||
else:
|
||||
return self.db["users"][user_id]["nom"]
|
||||
else:
|
||||
return "no specified user"
|
||||
else:
|
||||
if self.db["groups"].has_key(abs(user_id)):
|
||||
return self.db["groups"][abs(user_id)]
|
||||
return self.db["groups"][abs(user_id)]["nom"]
|
||||
else:
|
||||
return "no specified community"
|
||||
|
||||
@@ -297,14 +313,34 @@ class vkSession(object):
|
||||
self.db["groups"][i["id"]] = i["name"]
|
||||
|
||||
def process_usernames(self, data):
|
||||
""" processes user IDS and saves them in a local storage system.
|
||||
Every function wich needs to convert from an ID to user or community name will have to call the get_user_name function in this session object.
|
||||
Every function that needs to save a set ot user ids for a future use needs to pass a data dictionary with a profiles key being a list of user objects.
|
||||
For russian, it gets the genitive case of every name for future use."""
|
||||
log.debug("Adding usernames to the local database...")
|
||||
ids = ""
|
||||
for i in data["profiles"]:
|
||||
self.db["users"][i["id"]] = u"{0} {1}".format(i["first_name"], i["last_name"])
|
||||
if self.db["users"].has_key(i["id"]) == False:
|
||||
self.db["users"][i["id"]] = dict(nom=u"{0} {1}".format(i["first_name"], i["last_name"]))
|
||||
ids = ids + "{0},".format(i["id"],)
|
||||
gids = ""
|
||||
for i in data["groups"]:
|
||||
self.db["groups"][i["id"]] = i["name"]
|
||||
self.db["groups"][i["id"]] = dict(nom=i["name"])
|
||||
gids = "{0},".format(i["id"],)
|
||||
if not "ru" in languageHandler.getLanguage():
|
||||
return
|
||||
if ids != "":
|
||||
users_genitive = self.vk.client.users.get(user_ids=ids, fields="first_name, last_name", name_case="gen")
|
||||
users_instrumental = self.vk.client.users.get(user_ids=ids, fields="first_name, last_name", name_case="ins")
|
||||
for i in users_genitive:
|
||||
if self.db["users"].has_key(i["id"]):
|
||||
self.db["users"][i["id"]]["gen"] = u"{0} {1}".format(i["first_name"], i["last_name"])
|
||||
for i in users_instrumental:
|
||||
if self.db["users"].has_key(i["id"]):
|
||||
self.db["users"][i["id"]]["ins"] = u"{0} {1}".format(i["first_name"], i["last_name"])
|
||||
|
||||
def get_my_data(self):
|
||||
log.debug("Getting user identifier...")
|
||||
user = self.vk.client.users.get(fields="uid, first_name, last_name")
|
||||
self.user_id = user[0]["id"]
|
||||
self.db["users"][self.user_id] = u"{0} {1}".format(user[0]["first_name"], user[0]["last_name"])
|
||||
# self.db["users"][self.user_id] = u"{0} {1}".format(user[0]["first_name"], user[0]["last_name"])
|
||||
|
@@ -28,6 +28,7 @@ class sessionManagerController(object):
|
||||
strconfig = "%s/session.conf" % (paths.config_path(i))
|
||||
config_test = Configuration(strconfig)
|
||||
name = config_test["vk"]["user"]
|
||||
if name != "" and config_test["vk"]["password"] != "":
|
||||
self.session = i
|
||||
s = session.vkSession(self.session)
|
||||
s.get_configuration()
|
||||
|
@@ -8,7 +8,7 @@ class vkObject(object):
|
||||
|
||||
def __init__(self):
|
||||
self.api_key = keys.keyring.get_api_key()
|
||||
self.api_version = 5.45
|
||||
self.api_version = 5.52
|
||||
log.debug("Created vkSession using VK API Version %s" % (self.api_version,))
|
||||
|
||||
def login(self, user, password):
|
||||
|
@@ -23,6 +23,7 @@ class newSessionDialog(widgetUtils.BaseDialog):
|
||||
sizer.Add(b1, 0, wx.ALL, 5)
|
||||
sizer.Add(b2, 0, wx.ALL, 5)
|
||||
ok = wx.Button(panel, wx.ID_OK)
|
||||
ok.SetDefault()
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL)
|
||||
btnb = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnb.Add(ok, 0, wx.ALL, 5)
|
||||
|
@@ -141,7 +141,7 @@ class list(object):
|
||||
self.list.SetColumnWidth(column, characters_max*2)
|
||||
|
||||
def set_size(self):
|
||||
self.list.SetSize((self.list.GetBestSize()[0], 728))
|
||||
self.list.SetSize((self.list.GetBestSize()[0], 1000))
|
||||
|
||||
def create_list(self, parent):
|
||||
self.list = wx.ListCtrl(parent, -1, **self.listArguments)
|
||||
|
@@ -21,3 +21,9 @@ def show_error_code(code):
|
||||
title = _(u"Restricted access")
|
||||
message = _(u"Access to user's audio is denied by the owner. Error code {0}").format(code,)
|
||||
return wx.MessageDialog(None, message, title, style=wx.ICON_ERROR).ShowModal()
|
||||
|
||||
def bad_authorisation():
|
||||
return wx.MessageDialog(None, _(u"authorisation failed. Your configuration will not be saved. Please close and open again the application for authorising your account. Make sure you have typed your credentials correctly."), _(u"Error"), style=wx.ICON_ERROR).ShowModal()
|
||||
|
||||
def delete_audio_album():
|
||||
return wx.MessageDialog(None, _(u"Do you really want to delete this Album? this will be deleted from VK too."), _(u"Attention"), style=wx.ICON_QUESTION|wx.YES_NO).ShowModal()
|
||||
|
24
src/wxUI/dialogs/creation.py
Normal file
24
src/wxUI/dialogs/creation.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import wx
|
||||
import widgetUtils
|
||||
|
||||
class audio_album(widgetUtils.BaseDialog):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(audio_album, self).__init__(title=_(u"Create a new album"), parent=None)
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
lbl = wx.StaticText(panel, wx.NewId(), _(u"Album title"))
|
||||
self.title = wx.TextCtrl(panel, wx.NewId())
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
box.Add(lbl, 1, wx.ALL, 5)
|
||||
box.Add(self.title, 1, wx.ALL, 5)
|
||||
sizer.Add(box, 1, wx.ALL, 5)
|
||||
ok = wx.Button(panel, wx.ID_OK, _(u"&OK"))
|
||||
ok.SetDefault()
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close"))
|
||||
btnsizer = wx.BoxSizer()
|
||||
btnsizer.Add(ok, 0, wx.ALL, 5)
|
||||
btnsizer.Add(cancel, 0, wx.ALL, 5)
|
||||
sizer.Add(btnsizer, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
@@ -2,8 +2,8 @@
|
||||
import wx
|
||||
|
||||
class selectAlbum(wx.Dialog):
|
||||
def __init__(self, albums):
|
||||
super(selectAlbum, self).__init__(parent=None, title=_(u"Select the album where you will upload the photo"))
|
||||
def __init__(self, title, albums):
|
||||
super(selectAlbum, self).__init__(parent=None, title=title)
|
||||
panel = wx.Panel(self)
|
||||
self.lista = wx.ListBox(panel, -1, choices=albums)
|
||||
self.lista.SetFocus()
|
@@ -16,10 +16,12 @@ class timelineDialog(widgetUtils.BaseDialog):
|
||||
userSizer.Add(self.cb, 0, wx.ALL, 5)
|
||||
actionsstatic = wx.StaticBox(panel, label=_(u"Buffer type"))
|
||||
self.wall = wx.RadioButton(panel, wx.NewId(), _(u"&Wall posts"), style=wx.RB_GROUP)
|
||||
self.audio = wx.RadioButton(panel, wx.NewId(), _(u"&Audio"))
|
||||
self.audio = wx.RadioButton(panel, wx.NewId(), _(u"Audio"))
|
||||
self.friends = wx.RadioButton(panel, wx.NewId(), _(u"Friends"))
|
||||
radioSizer = wx.StaticBoxSizer(actionsstatic, wx.HORIZONTAL)
|
||||
radioSizer.Add(self.wall, 0, wx.ALL, 5)
|
||||
radioSizer.Add(self.audio, 0, wx.ALL, 5)
|
||||
radioSizer.Add(self.friends, 0, wx.ALL, 5)
|
||||
sizer.Add(radioSizer, 0, wx.ALL, 5)
|
||||
ok = wx.Button(panel, wx.ID_OK, _(u"&OK"))
|
||||
ok.SetDefault()
|
||||
@@ -39,3 +41,5 @@ class timelineDialog(widgetUtils.BaseDialog):
|
||||
return "audio"
|
||||
elif self.wall.GetValue() == True:
|
||||
return "wall"
|
||||
elif self.friends.GetValue() == True:
|
||||
return "friends"
|
@@ -6,12 +6,18 @@ class mainWindow(wx.Frame):
|
||||
def makeMenu(self):
|
||||
mb = wx.MenuBar()
|
||||
app_ = wx.Menu()
|
||||
create = wx.Menu()
|
||||
self.audio_album = create.Append(wx.NewId(), _(u"Audio album"))
|
||||
app_.AppendMenu(wx.NewId(), _(u"Create"), create)
|
||||
delete = wx.Menu()
|
||||
self.delete_audio_album = delete.Append(wx.NewId(), _(u"Audio album"))
|
||||
app_.AppendMenu(wx.NewId(), _(u"Delete"), delete)
|
||||
self.settings_dialog = app_.Append(wx.NewId(), _(u"Preferences"))
|
||||
buffer = wx.Menu()
|
||||
self.new_buffer = wx.Menu()
|
||||
self.search_audios = self.new_buffer.Append(wx.NewId(), _(u"Audio"))
|
||||
buffer.AppendMenu(wx.NewId(), _(u"Search"), self.new_buffer)
|
||||
search = wx.Menu()
|
||||
self.search_audios = search.Append(wx.NewId(), _(u"Audio"))
|
||||
self.timeline = buffer.Append(wx.NewId(), _(u"&New timeline"))
|
||||
buffer.AppendMenu(wx.NewId(), _(u"Search"), search)
|
||||
self.update_buffer = buffer.Append(wx.NewId(), _(u"Update current buffer"))
|
||||
self.load_previous_items = buffer.Append(wx.NewId(), _(u"Load previous items"))
|
||||
self.remove_buffer_ = buffer.Append(wx.NewId(), _(u"&Remove buffer"))
|
||||
@@ -19,6 +25,7 @@ class mainWindow(wx.Frame):
|
||||
mb.Append(buffer, _(u"Buffer"))
|
||||
help_ = wx.Menu()
|
||||
self.about = help_.Append(wx.NewId(), _(u"About {0}").format(application.name,))
|
||||
self.documentation = help_.Append(wx.NewId(), _(u"Manual"))
|
||||
self.check_for_updates = help_.Append(wx.NewId(), _(u"Check for updates"))
|
||||
self.changelog = help_.Append(wx.NewId(), _(u"Chan&gelog"))
|
||||
mb.Append(help_, _(u"Help"))
|
||||
@@ -26,16 +33,19 @@ class mainWindow(wx.Frame):
|
||||
|
||||
def __init__(self):
|
||||
super(mainWindow, self).__init__(parent=None, id=wx.NewId(), title=application.name)
|
||||
self.Maximize()
|
||||
self.makeMenu()
|
||||
self.panel = wx.Panel(self)
|
||||
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.sb = self.CreateStatusBar()
|
||||
self.tb = wx.Treebook(self.panel, -1)
|
||||
self.sizer.Add(self.tb, 0, wx.ALL, 5)
|
||||
self.sizer.Add(self.tb, 1, wx.ALL|wx.EXPAND, 5)
|
||||
|
||||
def realize(self):
|
||||
self.panel.SetSizer(self.sizer)
|
||||
self.SetClientSize(self.sizer.CalcMin())
|
||||
self.Layout()
|
||||
self.SetSize(self.GetBestSize())
|
||||
|
||||
def change_status(self, status):
|
||||
self.sb.SetStatusText(status)
|
||||
|
@@ -8,13 +8,14 @@ class postMenu(wx.Menu):
|
||||
self.AppendItem(self.open)
|
||||
self.like = wx.MenuItem(self, wx.NewId(), _(u"Like"))
|
||||
self.AppendItem(self.like)
|
||||
self.unlike = wx.MenuItem(self, wx.NewId(), _(u"Unlike"))
|
||||
self.AppendItem(self.unlike)
|
||||
self.dislike = wx.MenuItem(self, wx.NewId(), _(u"Dislike"))
|
||||
self.dislike.Enable(False)
|
||||
self.AppendItem(self.dislike)
|
||||
self.comment = wx.MenuItem(self, wx.NewId(), _(u"Add comment"))
|
||||
self.AppendItem(self.comment)
|
||||
self.post_in_wall = self.Append(wx.NewId(), _(u"Post to this profile"))
|
||||
self.AppendItem(self.post_in_wall)
|
||||
self.post_in_wall = wx.MenuItem(self, wx.NewId(), _(u"Post to this profile"))
|
||||
self.post_in_wall.Enable(False)
|
||||
self.AppendItem(self.post_in_wall)
|
||||
|
||||
def create_specific_post_options(self):
|
||||
self.update = wx.MenuItem(self, wx.NewId(), _(u"Update"))
|
||||
@@ -22,6 +23,30 @@ class postMenu(wx.Menu):
|
||||
self.delete = wx.MenuItem(self, wx.NewId(), _(u"Delete"))
|
||||
self.AppendItem(self.delete)
|
||||
|
||||
class audioMenu(wx.Menu):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(audioMenu, self).__init__(*args, **kwargs)
|
||||
self.open = wx.MenuItem(self, wx.NewId(), _(u"&Open"))
|
||||
self.AppendItem(self.open)
|
||||
self.play = wx.MenuItem(self, wx.NewId(), _(u"&Play"))
|
||||
self.AppendItem(self.play)
|
||||
self.library = wx.MenuItem(self, wx.NewId(), _(u"&Add to library"))
|
||||
self.AppendItem(self.library)
|
||||
self.move = wx.MenuItem(self, wx.NewId(), _(u"Move to album"))
|
||||
self.AppendItem(self.move)
|
||||
|
||||
class peopleMenu(wx.Menu):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(peopleMenu, self).__init__(*args, **kwargs)
|
||||
self.view_profile = wx.MenuItem(self, wx.NewId(), _(u"View profile"))
|
||||
self.AppendItem(self.view_profile)
|
||||
self.message = wx.MenuItem(self, wx.NewId(), _(u"Send a message"))
|
||||
self.AppendItem(self.message)
|
||||
self.timeline = wx.MenuItem(self, wx.NewId(), _(u"Open timeline"))
|
||||
self.AppendItem(self.timeline)
|
||||
self.view_profile.Enable(False)
|
||||
|
||||
class commentMenu(wx.Menu):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(commentMenu, self).__init__(*args, **kwargs)
|
||||
@@ -41,20 +66,3 @@ class notificationsMenu(wx.Menu):
|
||||
super(notificationsMenu, self).__init__()
|
||||
self.mark_as_read = wx.MenuItem(self, wx.NewId(), _(u"Mark as read"))
|
||||
self.AppendItem(self.mark_as_read)
|
||||
|
||||
class toolsMenu(wx.Menu):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(toolsMenu, self).__init__(*args, **kwargs)
|
||||
self.url = wx.MenuItem(self, -1, _(u"Open URL"))
|
||||
self.AppendItem(self.url)
|
||||
# self.url.Enable(False)
|
||||
self.translate = wx.MenuItem(self, -1, _(u"Translate"))
|
||||
self.AppendItem(self.translate)
|
||||
self.CheckSpelling = wx.MenuItem(self, -1, _(u"Check Spelling"))
|
||||
self.AppendItem(self.CheckSpelling)
|
||||
|
||||
class attachMenu(wx.Menu):
|
||||
def __init__(self):
|
||||
super(attachMenu, self).__init__()
|
||||
self.photo = wx.MenuItem(self, wx.NewId(), _(u"Picture"))
|
||||
self.AppendItem(self.photo)
|
||||
|
@@ -8,9 +8,9 @@ class homeTab(wx.Panel):
|
||||
def create_list(self):
|
||||
self.lbl = wx.StaticText(self, wx.NewId(), _(u"Po&sts"))
|
||||
self.list = widgetUtils.list(self, *[_(u"User"), _(u"Text"), _(u"Date")], style=wx.LC_REPORT)
|
||||
self.list.set_windows_size(0, 80)
|
||||
self.list.set_windows_size(1, 190)
|
||||
self.list.set_windows_size(2, 40)
|
||||
self.list.set_windows_size(0, 200)
|
||||
self.list.set_windows_size(1, 300)
|
||||
self.list.set_windows_size(2, 250)
|
||||
self.list.set_size()
|
||||
self.list.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnKeyDown)
|
||||
|
||||
@@ -26,22 +26,26 @@ class homeTab(wx.Panel):
|
||||
sizer.Add(self.postBox, 0, wx.ALL, 5)
|
||||
self.create_list()
|
||||
sizer.Add(self.lbl, 0, wx.ALL, 5)
|
||||
sizer.Add(self.list.list, 0, wx.ALL, 5)
|
||||
sizer.Add(self.list.list, 1, wx.EXPAND, 5)
|
||||
self.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
|
||||
def OnKeyDown(self, ev=None):
|
||||
pub.sendMessage("show-current-status", buffer=self.name)
|
||||
ev.Skip()
|
||||
|
||||
def showMenu(self, ev):
|
||||
if self.results.get_count() == 0: return
|
||||
if self.list.get_count() == 0: return
|
||||
pub.sendMessage("show-menu", position=ev.GetPosition())
|
||||
|
||||
def showMenuByKey(self, ev):
|
||||
if self.results.get_count() == 0: return
|
||||
if self.list.get_count() == 0: return
|
||||
if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU:
|
||||
pub.sendMessage("show-menu", position=self.results.list.GetPosition())
|
||||
|
||||
def set_focus_function(self, focus_function):
|
||||
self.list.list.Bind(wx.EVT_LIST_ITEM_FOCUSED, focus_function)
|
||||
|
||||
class feedTab(homeTab):
|
||||
def __init__(self, parent):
|
||||
super(feedTab, self).__init__(parent=parent)
|
||||
@@ -51,9 +55,9 @@ class audioTab(homeTab):
|
||||
def create_list(self):
|
||||
self.lbl = wx.StaticText(self, wx.NewId(), _(u"Mu&sic"))
|
||||
self.list = widgetUtils.list(self, *[_(u"Title"), _(u"Artist"), _(u"Duration")], style=wx.LC_REPORT)
|
||||
self.list.set_windows_size(0, 80)
|
||||
self.list.set_windows_size(1, 190)
|
||||
self.list.set_windows_size(2, 40)
|
||||
self.list.set_windows_size(0, 160)
|
||||
self.list.set_windows_size(1, 380)
|
||||
self.list.set_windows_size(2, 80)
|
||||
self.list.set_size()
|
||||
self.list.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnKeyDown)
|
||||
|
||||
@@ -66,6 +70,18 @@ class audioTab(homeTab):
|
||||
self.postBox.Add(self.play, 0, wx.ALL, 5)
|
||||
self.postBox.Add(self.play_all, 0, wx.ALL, 5)
|
||||
|
||||
class audioAlbumTab(audioTab):
|
||||
|
||||
def create_post_buttons(self):
|
||||
self.load = wx.Button(self, wx.NewId(), _(u"Load album"))
|
||||
self.post = wx.Button(self, -1, _(u"&Post"))
|
||||
self.play = wx.Button(self, -1, _(u"P&lay"))
|
||||
self.play_all = wx.Button(self, -1, _(u"Play &All"))
|
||||
self.postBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self.postBox.Add(self.post, 0, wx.ALL, 5)
|
||||
self.postBox.Add(self.play, 0, wx.ALL, 5)
|
||||
self.postBox.Add(self.play_all, 0, wx.ALL, 5)
|
||||
|
||||
class notificationsTab(homeTab):
|
||||
def __init__(self, parent):
|
||||
super(notificationsTab, self).__init__(parent=parent)
|
||||
@@ -139,6 +155,9 @@ class chatTab(wx.Panel):
|
||||
box.Add(self.text, 0, wx.ALL, 5)
|
||||
return box
|
||||
|
||||
def set_focus_function(self, focus_function):
|
||||
self.list.list.Bind(wx.EVT_LIST_ITEM_FOCUSED, focus_function)
|
||||
|
||||
class peopleTab(homeTab):
|
||||
|
||||
def create_list(self):
|
||||
|
@@ -1,4 +1,4 @@
|
||||
{"current_version": "0.13",
|
||||
"description": "Some bugfixes, included a changelog which can be accessed through the help menu.",
|
||||
{"current_version": "0.14",
|
||||
"description": "Added management for audio albums. Bugfixes. Updated translations. Added a context menu for some items. Unread chats will be opened at startup.",
|
||||
"downloads":
|
||||
{"Windows32": "https://github.com/manuelcortez/socializer/blob/master/nightly/socializer-nightly-build.zip?raw=true"}}
|
Reference in New Issue
Block a user